본문 바로가기

Data Science/Data Analysis

[프로그래머스] SQL | Join 2문제

출처 : 프로그래머스 SQL 고득점 Kit - JOIN

1. 주문량이 많은 아이스크림들 조회하기
2. 5월 식품들의 총매출 조회하기


1. 주문량이 많은 아이스크림들 조회하기

7월 아이스크림 총 주문량과 상반기의 아이스크림 총 주문량을 더한 값이 큰 순서대로 상위 3개의 맛을 조회

— 7월의 경우 같은 맛이더라도 다른 출하 번호가짐

— 정렬 조건은 총주문량을 더한 값을 내림차순

 

 

 

 

해설1 Join을 사용하지않고, union을 사용 (나의 답)

강의에서 배운 with절을 사용해 세로로 합친 = Union 임시테이블 생성 → group by flavor하되 order by에서 정렬기준을 주문량의 합으로 내림차순함.

  • 쿼리 내에서 반복적으로 사용하는 테이블을 정의해서, 반복x, 대용량 처리에서는 성능 저하 발생 가능
WITH BYJULY AS 
    ( SELECT *
    FROM  FIRST_HALF
    UNION DISTINCT
    SELECT *
    FROM JULY )
SELECT FLAVOR
FROM BYJULY
GROUP BY FLAVOR
ORDER BY SUM(TOTAL_ORDER) desc
LIMIT 3;

 

 

테이블을 세로로 합치기 UNION 

UNION ALL 중복허용 (DB에 따라서 UNION만 적게 되는 경우도 있음)

UNION DISTINCT - 중복을 제거하고 합침

JOIN UNION
테이블 가로 합치기, 새로운 column을 생성 테이블 가로 합치기, 데이터를 합치면서 새로운 row을 생성

 

  • Union으로 테이블을 합칠 때 주의점
    같아야 하는 것 달라도 되는 것
    컬럼 개수컬럼 데이터 타입 컬럼명
    - 첫 번째 SELECT 문의 컬럼명을 기준으로 결과가 구성
-- 2개의 테이블

SELECT *
FROM data.spotify_1990

UNION DISTINCT

SELECT *
FROM data.spotify_2000

--여러개의 테이블 : 뒤에 계속 UNION으로 연결

SELECT *
FROM data.spotify_1990

UNION ALL

SELECT *
FROM data.spotify_2000

UNION ALL

SELECT *
FROM data.spotify_2010

 

 

해설2: Join이용

  • 두 개의 테이블을 합치는 표준 SQL 문법
  • 여러 테이블 합칠 시 가독성이 안좋음
  1. LEFT JOIN FIRST_HALF 테이블의 모든 행을 유지하면서 FLAVOR가져옴
  2. COALESCE(B.TOTAL_ORDER, 0) 함수를 사용하여 JULY 테이블의 TOTAL_ORDER 열을 선택하고, 해당 값이 NULL인 경우에는 0으로 대체
  3. 각각의 아이스크림 맛에 대해 A.TOTAL_ORDERCOALESCE(B.TOTAL_ORDER, 0) 값을 더하여 총 주문량을 계산해, 총 주문량을 내림차순으로 정렬
  4. 아이스크림 맛 반환
SELECT
    A.FLAVOR
FROM
    FIRST_HALF A
LEFT JOIN JULY B ON
    A.FLAVOR = B.FLAVOR
GROUP BY
    A.FLAVOR
ORDER BY
    SUM(A.TOTAL_ORDER+ COALESCE(B.TOTAL_ORDER, 0)) DESC
    LIMIT 3

 

 

  • COALESCE(expr1, expr2, ...) : 여러 개의 인수를 받고, 첫 번째 NULL이 아닌 값을 반환합니다.
SELECT COALESCE(NULL, 5, 10);
-- 결과: 5
SELECT COALESCE(column_name, 'N/A') FROM table_name;
-- 특정 열의 값이 NULL인 경우 'N/A'로 대체하여 결과를 반환
  • IFNULL(expr1, expr2) (MYSQL): 두 개의 인수를 받고, 첫 번째 인수가 NULL이 아니면 그 값을 반환하고, NULL이면 두 번째 인수를 반환합니다.

 

 

 

2. 5월 식품들의 총매출 조회하기

FOOD_PRODUCTFOOD_ORDER 테이블에서 생산일자가 2022년 5월인 식품들의 식품 ID, 식품 이름, 총매출을 조회

— 결과는 총매출을 기준으로 내림차순 정렬, 식품 ID를 기준으로 오름차순 정렬

해설1

SELECT A.PRODUCT_ID, PRODUCT_NAME, SUM(AMOUNT * PRICE) AS TOTAL_SALES
FROM FOOD_ORDER A 
 JOIN FOOD_PRODUCT B
ON A.PRODUCT_ID = B.PRODUCT_ID
WHERE MONTH(PRODUCE_DATE) = 5
GROUP BY PRODUCT_ID
ORDER BY 3 DESC, 1 ;

 

 

SELECT에서 총매출액구할때 SUM을 안써서 틀림 

SUM(AMOUNT * PRICE) AS TOTAL_SALES AMOUNT * PRICE AS TOTAL_SALES
특정 상품의 월별 총 매출액을 계산
- 각각의 상품의 매출액을 모두 합산하여 결과를 반환
각각의 행에서 개별 상품의 매출액을 계산
- 각 행이 개별 주문의 매출액을 나타내며, GROUP BY 절에 의해 각 상품별로 그룹화

 

⇒ GROUP BY 절에는 집계 함수(sum,count 등)로 처리되지 않는 열은 포함하지 않는 것이 좋음

 

 

 

+ GROUP BY 쓸 때 지켜야 하는 규칙

  1. SELECT 절에는 GROUP BY 뒤에서 사용한 컬럼들만 사용
  2. SELECT 절에는 COUNT(), MAX() 등과 같은 집계 함수만 사용

GROUP BY 에 조건으로 걸린 것만, select절에서 쓸 수 있음. 조건이 안걸려있는데 쓰려면 어디에 써야할지 모름

  • GROUP BY 이후에 생성된 그룹은 하나의 그룹을 의미하지만, 여러 ROW가 포함된 것
  • group by 뒤에 쓰지않은 컬럼명을 select절에서 써서 조회하면 각 그룹의 row 중 해당 컬럼의 값을 어느 row에서 가져와야하는지 결정할 수 없음
SELECT SUBSTRING(address, 1,2) AS region ,AVG(age), gender , COUNT(*) 
FROM member
GROUP BY SUBSTRIONG(address, 1,2),gender
HAVING region IS NOT NULL ;

SELECT 절 뒤에 age를 바로 쓰는 건 안 되지만, AVG(age)처럼 집계 함수의 인자로 사용하는 건 괜찮음

  • 특정 row의 age값을 보여주는 것이아니라 , 그룹 내 모든 row들의 age 컬럼의 값의 평균값을 구하는 것이기 때문