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일 모두가 나오지 않아야합니다
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 ) ;