1주일째 고민중인 예약관련 일입니다. 0 1 2,331

by 태코팅 sql 예약 case not in [2019.05.28 18:54:47]


질의 결과.JPG (21,915Bytes)

    select s.pd_cd, s.st_cd, s.st_this_num,p .etp_cd
	from stock s, product p
	where p.pd_cd = s.pd_cd
    and to_date(substr(s.st_cd,-5), 'MM-DD') between to_date('05-06', 'MM-DD') and to_date('05-08', 'MM-DD');

이러한 코드의 결과값은 첨부해 두었습니다.

앞서 말씀드린 코드에서 Stock는 재고 테이블 Product는 상품 테이블 입니다.

쿼리문 실행시 나온 St_this_num 에대한 값이 0이면 검색햇던 기간내의 관련된 상품이 나오지 않도록 해아합니다

 

제가 시도해본 방법은  p.pd_cd not in(select pd_cd from stock where st_this_num = 0) 

and문에 Not in문을 사용하여 결과값이 포함된 pd_cd 코드 자체를 제외하는 구문으로 짜보았습니다만

 

이런식으로 할경우 이후 0이아닌 날짜에 대해 조회를 실시하면 이미 해당 pd_cd에 대한 코드가 제외된 상태이기 때문에 나오질 않습니다.

결과는 실패지요.. 

 

어떤식으로 해야 st_this_num = 0 이 포함되어 검색된 기간(st_cd) 을 모두 제외시킬수 있을까요..? 부탁드립니다..

 

ex) 예를 들어 1일부터 5일까지 하나라도 재고중 0이란 값이 있으면 1~5일 모두가 나오지 않아야합니다

 

 

by 마농 [2019.05.29 07:52:13]

1. 사용하신 to_date 방법은 연도 미입력으로 현재년도를 기준으로 날짜 변환됩니다.
- 윤년이 아닌 해에 윤년의 '02-29' 자료를 변환하게 되면 오류 발생됩니다.
- 날짜 변환이 필요한지 의문이네요? 그냥 문자 그대로 비교하면 됩니다.
2. 사용하신 NOT IN 의 문제는 서브쿼리 안에 날짜조건 없는 것입니다.
- 서브쿼리 안에 날짜 조건 추가하시면 됩니다.
3. st_cd 컬럼은
- 컬럼에 여러가지 의미를 담고 있네요.(상품 + 날짜)
- 날짜는 연도를 포함해야 합니다.
- 연도가 없이는 12월말부터 1월초까지의 예약을 구현하기 까다롭습니다.
- 기존 substr 사용으로 인해 인덱스를 사용하지 못하는 비효율도 있습니다.
- 날짜를 아예 별도로 분리하는 것이 좋습니다.(상품, 날짜)
- 이렇게 분리하면 아예 st_cd 컬럼은 불필요합니다.
- (상품, 날짜) 두개의 결합키가 st_cd 역할을 하게 됩니다.
 

-- 1. 분석함수
SELECT *
  FROM (SELECT s.pd_cd
             , s.st_cd
             , s.st_this_num
             , p.etp_cd
             , COUNT(DECODE(s.st_this_num, 0, 1)) OVER(PARTITION BY s.pd_cd) cnt
          FROM stock s
             , product p
         WHERE p.pd_cd = s.pd_cd
           AND SUBSTR(s.st_cd, -5) BETWEEN '05-06' AND '05-08'
        ) a
 WHERE cnt = 0
;
-- 2. Exists
SELECT s.pd_cd
     , s.st_cd
     , s.st_this_num
     , p.etp_cd
  FROM stock s
     , product p
 WHERE p.pd_cd = s.pd_cd
   AND SUBSTR(s.st_cd, -5) BETWEEN '05-06' AND '05-08'
   AND NOT EXISTS (SELECT 1
                     FROM stock x
                    WHERE x.pd_cd = s.pd_cd
                      AND SUBSTR(x.st_cd, -5) BETWEEN '05-06' AND '05-08'
                      AND x.st_this_num = 0
                   )
;

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입