본문 바로가기

SQL

SELECT 연습(2)

UNION ALL이란?

  • UNION ALL은 두 개 이상의 SELECT 결과를 합치면서(행끼리 합침) 중복된 데이터도 포함
  • 중복 데이터를 제거하지 않기 때문에 UNION보다 성능이 더 빠름

명시적 NULL 표기

 

  • 데이터 표현을 일관되게 유지하기 위해
  • 의도적으로 데이터가 없음을 표현

 

오프라인/온라인 판매 데이터 통합하기 (LV 4 💁😲)

처음에 결합은 당연히 join을 사용하는 것이라고 생각해서 풀었다가 생각해보니, join은 컬럼끼리 결합하는 것이지, 로우끼리 결합하는 것이 아니라는 생각이 들었다.. 그래서 한번 풀어보고 당연히 오답이 나와서 찾아본 결과 로우끼리의 결합은 uinon을 사용하여 한다는 것을 알게 되었다. 또 컬럼에 null을 아예 박아서 표기할 수 있다는 사실도 알게 되었다.... 역시 문제를 풀어보면서 여러 기능(?)들을 알게 되는 것 같다...(문풀의 중요성)

 

1차 풀이(당연히 오답인)

select date_format(o.SALES_DATE, '%Y-%m-%d') as SALES_DATE, o.PRODUCT_ID, o.USER_ID, o.SALES_AMOUNT
from ONLINE_SALE o
left join 
(SELECT SALES_DATE, PRODUCT_ID, SALES_AMOUNT
from OFFLINE_SALE
where SALES_DATE between '2022-03-01' and '2022-03-31'
 ) a on o.PRODUCT_ID = a.PRODUCT_ID
 where o.SALES_DATE between '2022-03-01' and '2022-03-31'
 order by 1 asc, 2 asc, 3 asc

 

 

2차 풀이

SELECT 
	SALES_DATE, 
    PRODUCT_ID, 
    USER_ID, 
    SALES_AMOUNT
FROM (
    SELECT 
        DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS 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 
        DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS 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 SALES_DATA
ORDER BY 
    SALES_DATE ASC, 
    PRODUCT_ID ASC, 
    USER_ID ASC;

 

 

업그레이드 된 아이템 구하기

처음에는 조건을 잘 못보고 희귀도가 'RARE'인걸 빼먹고 쿼리를 짰다 😅

하지만 생각을 해보니 저 조건을 어떻게 적용해야 할까 고민하다가 결국 join을 2번이나 하게해서 결과를 어떻게든 만들어 냈다..

근데 조인 2번이면 아무리 생각해도 너무 부담이 크도 비효율적으로 쿼리를 짠 것 같아서 냅다 gpt에게 짜보라고 시켰더니 in 조건 안에 서브쿼리를 짜서 넣어 풀었다 서브쿼리 결과를 그런 식으로 쓸 수 있는지는 처음 알았다!! 완전 유용하게 쓸 듯

 

join 2번 사용한 답

select c.ITEM_ID, c.ITEM_NAME, c.RARITY
from ITEM_INFO c
inner join 
    (
        select t.ITEM_ID
        from
        (
            select ITEM_ID, ITEM_NAME, RARITY
            from ITEM_INFO
            where RARITY = 'RARE'
        )a inner join ITEM_TREE t
                on a.ITEM_ID = t.PARENT_ITEM_ID
    )b on c.ITEM_ID = b.ITEM_ID
order by 1 desc

 

in 조건에 서브쿼리 넣어서 쓴 답

SELECT 
    i.ITEM_ID, 
    i.ITEM_NAME, 
    i.RARITY
FROM ITEM_INFO i
JOIN ITEM_TREE t
ON i.ITEM_ID = t.ITEM_ID
WHERE t.PARENT_ITEM_ID IN (
    SELECT ITEM_ID
    FROM ITEM_INFO
    WHERE RARITY = 'RARE'
)
ORDER BY i.ITEM_ID DESC;