쿼리 도와주세요 .. 0 9 1,196

by 김실홍 [SQL Query] [2016.03.16 15:20:02]



WITH TAB AS (
    SELECT 'A' GRP , 'AAA' KEY , '20160301' ST_DT , '20160331' ED_DT FROM DUAL
    UNION ALL
    SELECT 'A' GRP , 'BBB' KEY , '20160301' ST_DT , '20160331' ED_DT FROM DUAL
    UNION ALL
    SELECT 'B' GRP , 'AAA' KEY , '20160501' ST_DT , '20160531' ED_DT FROM DUAL
    UNION ALL
    SELECT 'B' GRP , 'BBB' KEY , '20160501' ST_DT , '20160531' ED_DT FROM DUAL
)
SELECT * FROM TAB A
WHERE '201603' BETWEEN SUBSTR(A.ST_DT, 0, 6) AND SUBSTR(A.ED_DT, 0, 6)


위처럼 조회하면

3월에 데이터만 조회되겠죠


--결과

GRP    KEY        ST_DT     ED_DT
 A     AAA        20160301  20160331
 A     BBB        20160301  20160331

 

제가 원하는 결과는

GRP    KEY        ST_DT     ED_DT
 A     AAA        20160301  20160331
 B     AAA        
 A     BBB         20160301  20160331
 B     BBB

 

 

만약 5월을 조회할 경우 

GRP    KEY        ST_DT     ED_DT
 A     AAA        
 B     AAA         20160501  20160531
 A     BBB        
 B     BBB          20160501  20160531

 


위처럼 기간에 걸리지 않더라고 그룹A 다음에는 그룹B를 보여주고 싶거든요

보통 이런경우  보통 유니온 시켰던거 같은데 

위 경우는 AAA 와 BBB가 여러건이 나오다 보니..

적용을 어떻게 해야될지 모르겠네요..

 

도와주세요.. ㅠㅠ


        

by 마농 [2016.03.16 15:37:14]

예시가 너무 간촐하여, 다양한 케이스의 예제가 필요해 보입니다.
1. 시작일과 종료일은 항상 월초부터 월말까지인가요?
  - 다른 일자가 나오는 경우는 없나요?
  - 1개월이 넘어가는 경우는 없나요?
2. '201604' 로 조회하면?
  - 아무것도 안나오면 되나요?
 


by 김실홍 [2016.03.16 15:39:39]

1. 시작일과 종료일은 항상 월초부터 월말까지인가요?
    - 다른날짜가 나올수 있습니다..  물론 1개월이 넘어갈수도있습니다
2. '201604' 로 조회하면?
  - 위 데이터라면 아무것도 안나오는게 맞습니다.

 

 

 


by swlee710 [2016.03.16 15:39:29]
WITH TAB AS (
     SELECT 'A' GRP , 'AAA' KEY , '20160301' ST_DT , '20160331' ED_DT FROM DUAL
     UNION ALL
     SELECT 'A' GRP , 'BBB' KEY , '20160301' ST_DT , '20160331' ED_DT FROM DUAL
     UNION ALL
     SELECT 'B' GRP , 'AAA' KEY , '20160501' ST_DT , '20160531' ED_DT FROM DUAL
     UNION ALL
     SELECT 'B' GRP , 'BBB' KEY , '20160501' ST_DT , '20160531' ED_DT FROM DUAL
 )
 SELECT grp, key
       , case when '201603' between SUBSTR(A.ST_DT, 0, 6) AND SUBSTR(A.ED_DT, 0, 6) then st_dt end st_dt
       , case when '201603' between SUBSTR(A.ST_DT, 0, 6) AND SUBSTR(A.ED_DT, 0, 6) then ED_DT end ED_DT
 FROM TAB A
 order by key, grp;

 


by 김실홍 [2016.03.16 15:43:38]

WHERE 절이 없어서 모든 데이터를 가져오게끔 됩니다.. ㅠㅠ양이 많습니다.


by 마농 [2016.03.16 16:04:30]
SELECT a.grp
     , b.key
     , b.st_dt
     , b.ed_dt
  FROM (SELECT 'A' grp FROM dual
        UNION ALL SELECT 'B' FROM dual
        ) a
  LEFT OUTER JOIN
       (SELECT *
          FROM tab
         WHERE st_dt <= '201603'||'31'
           AND ed_dt >= '201603'||'01'
        ) b
 PARTITION BY (b.key)
    ON a.grp = b.grp
 ORDER BY key, grp
;

 


by 김실홍 [2016.03.16 16:30:50]

마농님 감사합니다 근데 

LEFT OUTTER JOIN  

 

오라클에서만 쓰는 (+)  <- 이런식으로 바꿔주실수 있나요 ㅠㅠ..?

 

파티션 바이를 어떻게 넣어야 되는지 정확하게 모르겠네요 


by 김실홍 [2016.03.16 16:45:58]

헉 답변채택 버튼을 잘못눌럿네요 ㅠㅠ


by 마농 [2016.03.16 16:42:27]

PARTITION OUTER JOIN 은 ANSI 구문에서만 쓸 수 있는 구문입니다.
오라클 (+) 로 바꾸면 PATITION BY 쓸 수 없어서
쿼리가 더 복잡해지고, 성능도 느려집니다.
(+) 로 바꾸려는 특별한 이유라도 있나요?

SELECT a.grp
     , a.key
     , b.st_dt
     , b.ed_dt
  FROM (SELECT x.grp, y.key
          FROM (SELECT 'A' grp FROM dual
                UNION ALL SELECT 'B' FROM dual
                ) x
             , (SELECT DISTINCT key
                  FROM tab
                 WHERE st_dt <= '201603'||'31'
                   AND ed_dt >= '201603'||'01'
                ) y
        ) a
     , (SELECT *
          FROM tab
         WHERE st_dt <= '201603'||'31'
           AND ed_dt >= '201603'||'01'
        ) b
 WHERE a.grp = b.grp(+)
   AND a.key = b.key(+)
 ORDER BY key, grp
;

 


by 김실홍 [2016.03.16 16:45:18]

이유는 제가 익숙하지 않아서 인거 밖에 없습니다

 

아 파티션바이를 아우터 조인과 쓸때

안시쿼리로만 되는것을 몰랏네요..

 

아무튼 너무 감사드립니다 해결됬습니다. ㅠㅠ

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