[SELECT 별칭] 서브쿼리 쓰기 vs 안쓰기

dragonloly·2025년 2월 17일
0

SQL

목록 보기
11/19

SELECT 절의 별칭은 서브쿼리를 쓴다면 UNION 후에, 서브쿼리를 쓰지 않는다면 UNION 전에 별칭을 적용해놔야 한다.

UNION ALL을 수행하기 전에 각 SELECT 절에서 미리 DATE_FORMAT을 적용해야함

이유 ✅
UNION ALL을 하면 컬럼명이 첫 번째 SELECT 절을 기준으로 결정됨
즉, DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE를 한쪽에서만 적용하면 다른 테이블과 UNION ALL할 때 데이터 타입이 맞지 않을 수 있음
일관된 컬럼 형식을 유지하려면 두 테이블에서 모두 변환 후 UNION ALL해야 함

SELECT DATE_FORMAT(ONS.SALES_DATE, '%Y-%m-%d') AS SALES_DATE, 
       ONS.PRODUCT_ID, 
       ONS.USER_ID, 
       ONS.SALES_AMOUNT
FROM ONLINE_SALE AS ONS 
WHERE ONS.SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'

UNION ALL 

SELECT DATE_FORMAT(OFS.SALES_DATE, '%Y-%m-%d') AS SALES_DATE, 
       OFS.PRODUCT_ID, 
       'NULL' AS USER_ID, 
       OFS.SALES_AMOUNT
FROM OFFLINE_SALE AS OFS
WHERE OFS.SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'

ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;

서브쿼리 사용 방식

SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE, 
       PRODUCT_ID, 
       USER_ID, 
       SALES_AMOUNT
FROM (
    SELECT SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT 
    FROM ONLINE_SALE
    WHERE SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'

    UNION ALL

    SELECT SALES_DATE, PRODUCT_ID, 'NULL' AS USER_ID, SALES_AMOUNT
    FROM OFFLINE_SALE
    WHERE SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'
) AS COMBINED_DATA
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;

✔ 서브쿼리를 사용하면 DATE_FORMAT을 한 번만 적용할 수 있음
✔ 하지만 불필요한 데이터까지 UNION ALL 후 필터링되므로 비효율적일 수도 있음

합치기 전에 날짜를 3월 BETWEEN AND 하지말고, 합친 후에 BETWEEN AND 를 WHERE 절에 쓰면 안돼?

SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE, 
       PRODUCT_ID, 
       USER_ID, 
       SALES_AMOUNT
FROM (
    SELECT SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT 
    FROM ONLINE_SALE

    UNION ALL

    SELECT SALES_DATE, PRODUCT_ID, 'NULL' AS USER_ID, SALES_AMOUNT
    FROM OFFLINE_SALE
) AS COMBINED_DATA
WHERE SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'  -- ❌ 여기서 문제 발생!
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;

🚨 문제점
DATE_FORMAT(SALES_DATE, '%Y-%m-%d')을 적용하면 SALES_DATE가 문자열(VARCHAR)이 됨
그런데 WHERE SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'에서
👉 SALES_DATE는 이제 문자열이니까, 숫자로 된 날짜 비교(BETWEEN 연산)가 정확하게 동작하지 않을 수 있음!
날짜 비교는 DATE 타입으로 해야 정확함!

합친 후에 WHERE로 필터링하면 안 되는 이유!
네, 이 방식에서는 WHERE SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'을 UNION ALL 후에 적용하면 안 됩니다.
왜냐하면 SALES_DATE가 DATE_FORMAT()을 거친 후 문자열(VARCHAR)로 변환되기 때문이에요!

즉, WHERE절에서는 날짜가 3월로나오는데, SELECT 에서는 정작 문자열이니까 필터링이 안됨.

👉 WHERE SALES_DATE BETWEEN '2022-03-01' AND '2022-03-31'
👉 SALES_DATE가 DATE 타입이어야 날짜 비교가 정확하게 동작하는데, DATE_FORMAT()을 거친 후에는 문자열(VARCHAR)이 되니까 필터링이 안 될 수도 있어요!

결론: WHERE 필터링은 항상 DATE 타입 상태에서!
🚀 날짜 조건(BETWEEN)을 사용할 때는 항상 DATE 타입 상태에서 먼저 필터링하고, 그 후에 DATE_FORMAT()을 적용하자!

✅ 왜 이게 더 좋을까?
필터링을 먼저 하면 UNION ALL이 처리해야 할 데이터가 줄어들어 성능이 더 좋음!
👉 즉, 불필요한 데이터까지 UNION ALL 하지 않음
WHERE에서 DATE 타입으로 날짜 비교가 정확하게 동작함!
나중에 DATE_FORMAT()을 적용하더라도 날짜 비교 문제가 없음!

✅ 결론
서브쿼리 없이 UNION ALL 전에 각 테이블에서 DATE_FORMAT을 적용하는 것이 더 효율적
서브쿼리를 쓰면 DATE_FORMAT을 한 번만 적용할 수 있지만, 성능상 불리할 수도

profile
IT기업에서 운영 기획 담당하고 있습니다 : )

0개의 댓글