[TIL]_2025.03.10 본캠프 22일차 (1): 코드카타 SQL

JIYUU·2025년 3월 10일

71번. 오프라인/온라인 판매 데이터 통합하기

다음은 어느 의류 쇼핑몰의 온라인 상품 판매 정보를 담은 ONLINE_SALE 테이블과 오프라인 상품 판매 정보를 담은 OFFLINE_SALE 테이블 입니다. ONLINE_SALE 테이블은 아래와 같은 구조로 되어있으며 ONLINE_SALE_ID, USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE는 각각 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.
동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.

OFFLINE_SALE 테이블은 아래와 같은 구조로 되어있으며 OFFLINE_SALE_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE는 각각 오프라인 상품 판매 ID, 상품 ID, 판매량, 판매일을 나타냅니다.
동일한 날짜, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.

ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요.
OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요.
결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요.

  • 조회하려는 데이터 : 온오프라인 상품 판매 데이터 판매 날짜, 상품 ID, 유저 ID, 판매량
  • 조건 : 2022-03, 오프라인일 경우 유저 ID는 NULL
  • 정렬 : 판매일 기준 ASC, 상품 ID ASC, 유저 ID, ASC
SELECT *
FROM
(SELECT 
    DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE,
    PRODUCT_ID,
    USER_ID,
    SALES_AMOUNT
FROM ONLINE_SALE
UNION ALL
SELECT 
    DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE, 
    PRODUCT_ID,
    NULL AS USER_ID,
    SALES_AMOUNT
FROM OFFLINE_SALE) AS ONOFF
WHERE SALES_DATE LIKE '2022-03%'
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;

두 테이블을 UNION해야하는데, UNION을 하기 위해서는 병합하려는 두 테이블의 컬럼 개수가 같아야한다.
따라서 OFFLINE 테이블의 USER_ID 컬럼을 NULL로 만들어주고 병합한 뒤,
문제의 조건에 따라서 WHERE절을 작성하고, 정렬하면 된다.

72번. 조건에 부합하는 중고거래 댓글 조회하기

USED_GOODS_BOARD와 USED_GOODS_REPLY 테이블에서 2022년 10월에 작성된 게시글 제목, 게시글 ID, 댓글 ID, 댓글 작성자 ID, 댓글 내용, 댓글 작성일을 조회하는 SQL문을 작성해주세요. 결과는 댓글 작성일을 기준으로 오름차순 정렬해주시고, 댓글 작성일이 같다면 게시글 제목을 기준으로 오름차순 정렬해주세요.

  • 조회하려는 데이터 : TITLE, BOARD_ID, REPLY_ID, WRITER_ID, CONTENTS, CREATED_DATE
  • 조건 : 2022-10
  • 정렬 : 댓글 작성일 기준 ASC, 게시글 제목 ASC
SELECT 
    UGB.TITLE,
    UGB.BOARD_ID, 
    UGR.REPLY_ID,
    UGR.WRITER_ID,
    UGR.CONTENTS,
    DATE_FORMAT(UGR.CREATED_DATE, '%Y-%m-%d') AS CREATED_DATE
FROM USED_GOODS_BOARD UGB
JOIN USED_GOODS_REPLY UGR
ON UGB.BOARD_ID = UGR.BOARD_ID
WHERE UGB.CREATED_DATE LIKE '2022-10%'
ORDER BY UGR.CREATED_DATE, UGB.TITLE;

갑자기 이전 문제들 대비 낮아져서 풀면서도 이게 맞는지 살짝 의심스러웠지만 정답을 바로 맞췄다.
게시글에 작성된 댓글에 대한 테이블이므로, 댓글이 안달린 경우는 제외 가능하여 INNER JOIN으로 JOIN했고, 나머지는 조건에 맞춰서 작성했다.

73번. 입양 시각 구하기(2)

ANIMAL_OUTS 테이블을 이용하여,
보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

  • 조회하려는 데이터 : 시간대별 입양 건 수
  • 조건 : 0시~ 23시 시간대별 입양 건 수 (COUNT)
  • 정렬 : 시간대순 ASC

처음에 문제를 풀었을 때에는 GROUP이나 CASE WHEN으로 풀려고 했으나, CASE WHEN의 경우.. 23번을 작성해야 하는데 왠지 아닌 것 같아서 구글링을 좀 해봤다.
SET이라는 명령어를 통해서 사용자 정의 변수를 설정할 수 있다고 한다.

SET @변수명 = 값;

SET @sales = 1000, @tax = 100, @total = @sales + @tax;
-- 변수를 여러 개를 설정할 수도 있고, 다른 변수의 값을 계산할 수도 있음
SET @HOUR = -1; -- 변수를 -1로 설정
SELECT 
	(@HOUR := @HOUR +1) AS HOUR,
	(SELECT COUNT(ANIMAL_ID)
	FROM ANIMAL_OUTS
	WHERE @HOUR = HOUR(DATETIME)) AS COUNT
FROM ANIMAL_OUTS
WHERE @HOUR < 23; -- @HOUR가 23보다 작을 때까지 진행되며 0~23이 출력될 것임

갑자기 SET이라는 변수 명령어가 나와서 당황했지만 새로운 기능을 또 배울 수 있었다.

0개의 댓글