관리 메뉴

블로그

[Programmers] 133027 - 주문량이 많은 아이스크림들 조회하기 SQL MySQL 본문

공부

[Programmers] 133027 - 주문량이 많은 아이스크림들 조회하기 SQL MySQL

beenu 2024. 10. 31. 05:27
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/133027

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

# 첫 번째 아이디어

FULL OUTER JOIN 방식으로 두 테이블 합치고 WITH 사용해서 임시 테이블 생성

다시봐도 개구린 코드구만 ;;

WITH TMP AS
(SELECT IFNULL(F.FLAVOR, J.FLAVOR) AS F_FLAVOR, IFNULL(J.FLAVOR, F.FLAVOR) AS J_FLAVOR, IFNULL(F.TOTAL_ORDER, 0) AS F_ORDER, IFNULL(J.TOTAL_ORDER, 0) AS J_ORDER
FROM FIRST_HALF F
LEFT JOIN JULY J ON F.SHIPMENT_ID = J.SHIPMENT_ID
UNION
SELECT IFNULL(F.FLAVOR, J.FLAVOR) AS F_FLAVOR, IFNULL(J.FLAVOR, F.FLAVOR) AS J_FLAVOR, IFNULL(F.TOTAL_ORDER, 0) AS F_ORDER, IFNULL(J.TOTAL_ORDER, 0) AS J_ORDER
FROM FIRST_HALF F
RIGHT JOIN JULY J ON F.SHIPMENT_ID = J.SHIPMENT_ID;)

 

암튼 생각처럼 잘 안돼서 다른 분 블로그 참고함 >.<

두 번째, 세 번째 코드는 블로그 참고해서 짠 코드


 

# 두 번째 : UNION ALL 사용

SELECT FLAVOR
FROM (SELECT FLAVOR, SUM(TOTAL_ORDER) AS TOTAL_ORDER
      FROM (SELECT FLAVOR, TOTAL_ORDER FROM FIRST_HALF
            UNION ALL
            SELECT FLAVOR, TOTAL_ORDER FROM JULY) 
            AS UNION_TMP
      GROUP BY FLAVOR) 
      AS GROUP_TMP
ORDER BY TOTAL_ORDER DESC
LIMIT 3;

 

제일 안쪽 괄호 > FIRST_HALF와 JULY를 UNION ALL로 합친다. 이렇게 하면 FIRST_HALF와 JULY의 모든 FLAVOR, TOTAL_ORDER가 CONCAT 형식으로 붙음 ! UNION ALL은 중복 제거 안하기 때문에 모든 행이 다 붙는다.

 

이렇게 만든 테이블을 UNION_TMP라고 이름 짓고 FLAVOR 기준으로 그룹화 한 후, TOTAL_ORDER 합계 기준으로 내림차순 정렬한다.

 

마지막으로 상위 세 개 FLAVOR만 출력하면 끝 !

 


 

# 세 번째 : JULY 우선 그룹화 

SELECT F.FLAVOR
FROM FIRST_HALF F
     JOIN (SELECT FLAVOR, SUM(TOTAL_ORDER) AS JULY_TOTAL_ORDER
           FROM JULY
           GROUP BY FLAVOR) J
     ON F.FLAVOR = J.FLAVOR
ORDER BY TOTAL_ORDER + JULY_TOTAL_ORDER DESC
LIMIT 3;

 

FIRST_HALF 테이블은 상반기 동안의 주문 내역이 모두 그룹화 되어있지만, JULY 테이블은 중복되는 FLAVOR들이 존재함 ! (그룹화 되어있지 않음) => 따라서 먼저 JULY 테이블을 FLAVOR 기준으로 그룹핑해준다.

 

이후에 FIRST_HALF와 JOIN하고 정렬, 상위 세 개 출력하면 끝 ~

 

나는 INNER JOIN을 사용하면 두 테이블에 공통으로 존재하는 맛만 가져오니까

한쪽 테이블에만 있는 맛이 다른 맛들의 총 주문량보다 많은 경우는 확인할 수 없다고 생각해서  FULL OUTER JOIN을 사용하고 싶었던 건데 INNER JOIN해도 상관없는 거였다...

 


 

# 마지막 : FULL OUTER JOIN 사용

SELECT FLAVOR
FROM (
    SELECT COALESCE(F.FLAVOR, J.FLAVOR) AS FLAVOR,
           COALESCE(F.TOTAL_ORDER, 0) AS FIRST_HALF_ORDER,
           COALESCE(J.JULY_TOTAL_ORDER, 0) AS JULY_ORDER
    FROM FIRST_HALF F
    LEFT JOIN (
        SELECT FLAVOR, SUM(TOTAL_ORDER) AS JULY_TOTAL_ORDER
        FROM JULY
        GROUP BY FLAVOR
    ) J ON F.FLAVOR = J.FLAVOR

    UNION

    SELECT COALESCE(F.FLAVOR, J.FLAVOR) AS FLAVOR,
           COALESCE(F.TOTAL_ORDER, 0) AS FIRST_HALF_ORDER,
           COALESCE(J.JULY_TOTAL_ORDER, 0) AS JULY_ORDER
    FROM (
        SELECT FLAVOR, SUM(TOTAL_ORDER) AS JULY_TOTAL_ORDER
        FROM JULY
        GROUP BY FLAVOR
    ) J
    RIGHT JOIN FIRST_HALF F ON F.FLAVOR = J.FLAVOR
) AS FULL_OUTER_JOIN_RESULT
ORDER BY FIRST_HALF_ORDER + JULY_ORDER DESC
LIMIT 3;

 

아쉬우니까 지피티한테 코드 짜달라고 했다 ^^

COALESCE는 IFNULL처럼 NULL 대체할 때 쓰는 함수다.

IFNULL은 MySQL에만 제공되는 함수고 두 값만 넣을 수 있지만, COALESCE는 표준 SQL 함수고 여러 개를 넣을 수 있음 

 

https://www.w3schools.com/sql/sql_join_full.asp

MySQL에서 FULL OUTER JOIN 구현할라면 LEFT OUTER JOIN, RIGHT OUTER JOIN하고 UNION으로 합쳐서 중복 제거해주면 됨 

 

앞으로 FULL OUTER JOIN이 쓰고 싶어지면 UNION ALL을 쓰자.. 훨 간단하네

 

 

>> 참고 블로그

UNION, JOIN 방식 둘 다 사용하셔서 유익했다 !

https://eunsun-zizone-zzang.tistory.com/93

 

[프로그래머스/SQL] 주문량이 많은 아이스크림들 조회하기

https://school.programmers.co.kr/learn/courses/30/lessons/133027 프로그래머스코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞

eunsun-zizone-zzang.tistory.com

 

 

728x90
반응형