union all 관련 질문입니다. 0 7 653

by 달라쏭 [SQL Query] [2018.04.10 09:50:33]


예를 들어 같은 테이블에서 조건만 다른 것들을 합쳐서 추출하려고 할때요. 무식(?) 하게는
SELECT HPNO, 'A1' KIND
FROM TB_1
WHERE VALID_DATE = TO_CHAR(SYSDATE + 1, 'YYYYMMDD')

UNION ALL

SELECT HPNO, 'A2' KIND
FROM TB_1
WHERE VALID_DATE = TO_CHAR(SYSDATE + 7, 'YYYYMMDD')

UNION ALL

SELECT HPNO, 'A3' KIND
FROM TB_1
WHERE VALID_DATE = TO_CHAR(SYSDATE + 30, 'YYYYMMDD')

이걸 아래와 같이 SELECT 절에서 CASE 로 표현 하기도 할텐데요.

SELECT HPNO, CASE WHEN VALID_DATE = TO_CHAR(SYSDATE+1,'YYYYMMDD') THEN 'A1'
                          WHEN VALID_DATE = TO_CHAR(SYSDATE+7,'YYYYMMDD') THEN 'A2'
                          WHEN VALID_DATE = TO_CHAR(SYSDATE+30,'YYYYMMDD') THEN 'A3' END AS KIND
FROM TB_1

WHERE ( VALID_DATE = TO_CHAR(SYSDATE + 1, 'YYYYMMDD')
                OR VALID_DATE = TO_CHAR(SYSDATE + 7 'YYYYMMDD')
                OR VALID_DATE = TO_CHAR(SYSDATE + 30, 'YYYYMMDD')
               );           

 

이런 방법 말고 다른 방법이 또 있을까요?

* VALID_DATE 는 인덱스 걸려있고 VARCHAR2 형태입니다.

by 우리집아찌 [2018.04.10 09:58:44]
-- 컬럼이 VARCHAR2라 좀 복잡하게 짜졌네요.
-- OR 싫으시면 IN 절로... 그게 그거지만요.

WITH T AS (
SELECT TO_CHAR(SYSDATE + LEVEL - 1 ,'YYYYMMDD') DT FROM DUAL CONNECT BY LEVEL <= 50
)

SELECT * FROM T 
 WHERE DT IN ( TO_CHAR(SYSDATE+1,'YYYYMMDD') , TO_CHAR(SYSDATE+7,'YYYYMMDD'), TO_CHAR(SYSDATE+30,'YYYYMMDD') )
 

 


by 우리집아찌 [2018.04.10 10:03:42]

다른 조건들이 많이 붙을경우 IN절이 가독성이 더 좋은거 같으네요. ( 괄호를 써야 하는경우가 많아서)

OR은 왠지 잘 안쓰게 됩니다.


by 우리집아찌 [2018.04.10 10:05:55]
-- 조인으로..
WITH T AS (
SELECT TO_CHAR(SYSDATE + LEVEL ,'YYYYMMDD') DT , LEVEL  LV  FROM DUAL CONNECT BY LEVEL <= 30
)

SELECT * 
 FROM TB_1 A
    , T B 
 WHERE A.VALID_DAT = B.DT
   AND B.LV IN ( 1 , 7 , 30 ) 

 


by 신이만든지기 [2018.04.10 10:00:01]

valid_date in (to_char(sysdate + 1, 'YYYYMMDD'), to_char('sysdate + 7, 'YYYYMMDD'))

OR 대신 IN절을 사용하는 방법도 있겠습니다만, 성능은 같게 나올것 같네요.

말씀하신 방법중 아래방법이 최선인 것 같습니다. 


by 달라쏭 [2018.04.10 10:41:37]

답변 감사합니다.

두번째 방법이 현재는 실행계획에서 볼때 비용은 더 적게 나오긴 하는데.... 

or 절은 인덱스 안타고 풀탄다는 소문이.... 두번째로 해도 현재는 range scan 을 하네요,.. 뭐징~~~

 

 


by 우리집아찌 [2018.04.10 10:58:17]

첫번째가 COST 덜 들듯한데 ㅎㅎㅎ 잘모르겟네요.

VALID_DAT가 유니크 하지 않으시면 RANGE SCAN으로 처리하겠죠.

OR이 풀탄다는건 잘못된 소문입니다.

http://wiki.gurubee.net/pages/viewpage.action?pageId=4949506


by 달라쏭 [2018.04.10 11:39:24]

둘다 range scan 으로 처리 하게 된다면 

테이블을 한번만 스캔하는 밑에게 비용이 덜들긴 합니다. ㅎㅎ

만약 밑에것이 인덱스 없이 풀을 탄다면

세번의 테이블 스캔에 인덱스를 탈것이냐  아니면 한번의 풀스캔이냐.  라는 고민을 할수는 있을겉 같습니다만 ㅎㅎ

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