본문 바로가기

Skill Sets/SQL

[SQL] 가격대 별 상품 개수 구하기(프로그래머스/MySQL/Level 2)

SMALL

안녕하세요! 데코입니다!

오늘은 프로그래머스 코딩테스트 연습에 있는 "가격대 별 상품 개수 구하기" 문제를 포스팅하려고 합니다!

 

바로 포스팅 시작할게요! :)

(출처 : https://school.programmers.co.kr/learn/courses/30/lessons/131530)

1. 문제 :  가격대 별 상품 개수 구하기(Lv. 2)

2. 문제 설명

다음은 어느 의류 쇼핑몰에서 판매중인 상품들의 정보를 담은 PRODUCT 테이블입니다.

PRODUCT 테이블은 아래와 같은 구조로 되어있으며,

PRODUCT_ID, PRODUCT_CODE, PRICE는 각각 상품 ID, 상품코드, 판매가를 나타냅니다.

 

[ 테이블 구조 ]

NAME TYPE NULLABLE
PRODUCT_ID INTEGER FALSE
PRODUCT_CODE VARCHAR(8) FALSE
PRICE INTEGER FALSE

상품 별로 중복되지 않는 8자리 상품코드 값을 가지며,

 앞 2자리는 카테고리 코드를 의미합니다.

 

[ 문제 ]

PRODUCT 테이블에서 만원 단위의 가격대 별로 상품 개수를 출력하는 SQL 문을 작성해주세요.
이때 컬럼명은 각각 컬럼명은 PRICE_GROUP, PRODUCTS로 지정해주시고
가격대 정보는 각 구간의 최소금액(10,000원 이상 ~ 20,000 미만인 구간인 경우 10,000)으로 표시해주세요.
결과는 가격대를 기준으로 오름차순 정렬해주세요.

 

[ 예시 ]

예를 들어 PRODUCT 테이블이 다음과 같다면

PRODUCT_ID PRODUCT_CODE PRICE
1 A1000011 10000
2 A1000045 9000
3 C3000002 22000
4 C3000006 15000
5 C3000010 30000
6 K1000023 17000

만원 단위의 가격대 별로 상품을 나누면

 

-  가격대가 0원 ~ 1만원 미만인 상품은 PRODUCT_ID 가 2인 상품 1개,

-  가격대가 1만원 이상 ~ 2만원 미만인 상품들은 PRODUCT_ID 가 1, 4, 6인 상품 3개,

-  가격대가 2만원 이상 ~ 3만원 미만인 상품은 PRODUCT_ID 가 3인 상품 1개,

- 가격대가 3만원 이상 ~ 4만원 미만인 상품은 PRODUCT_ID 가 5인 상품 1개,

 

에 각각 해당하므로 다음과 같이 결과가 나와야 합니다.

 

[ 출력 결과 ]

PRICE_GROUP PRODUCTS
0 1
10000 3
20000 1
30000 1

 

3. 문제 풀이

# 1안
SELECT  FLOOR(PRICE/10000)*10000 AS PRICE_GROUP
        , COUNT(*) AS PRODUCTS
  FROM  product
 GROUP 
    BY  PRICE_GROUP
 ORDER
    BY  PRICE_GROUP ASC
    
# 2안
SELECT  CASE WHEN (0 < PRICE) AND (PRICE < 10000) then 0
             WHEN (10000 <= PRICE) and (PRICE < 20000) then 10000
             WHEN (20000 <= PRICE) and (PRICE < 30000) then 20000
             WHEN (30000 <= PRICE) and (PRICE < 40000) then 30000
             WHEN (40000 <= PRICE) and (PRICE < 50000) then 40000
             WHEN (50000 <= PRICE) and (PRICE < 60000) then 50000
             WHEN (60000 <= PRICE) and (PRICE < 70000) then 60000
             WHEN (70000 <= PRICE) and (PRICE < 80000) then 70000
             WHEN (80000 <= PRICE) and (PRICE < 90000) then 80000
             END AS PRICE_GROUP, count(*)
  FROM  PRODUCT 
 GROUP 
    BY  PRICE_GROUP
 ORDER
    BY  PRICE_GROUP ASC

이번 문제는 1안과 2안 두 가지로 작성했습니다!

#  풀이 설명

# [ 문제 접근 설명 ]

이번 문제의 요구 사항을 정리해보면,

 

연속형 데이터인 'PRICE' 컬럼을 만원 단위로 범주화하여 이를 'PRICE_GROUP' 컬럼으로 만들고

집계하는 문제입니다.

 

# [ 1안 쿼리 작성 설명 ]

PRODUCT 테이블에 존재하는 컬럼들이 [출력 결과]에 나와 있는 컬럼들과 동일하게

 

" SELECT "문에 통해 'PRICE' 컬럼의 값을 10000으로 나누고

이를  'FLOOR()' 함수를 이용해서 소수점을 제거 및 10000을 곱하여 값을 산출

해당 값을 가진 컬럼명을 'PRICE_GROUP'으로 나타나도록 변경(Alias를 이용한 별칭 설정)

" FLOOR(PRICE/10000) * 10000 " 의미(만원 단위 구분)

이후에

" GROUP BY {컬럼} "을 통해 생성한 'PRICE_GROUP'별로 집계 실행

" ORDER BY {컬럼} ASC "를 통해 생성한 'PRICE_GROUP' 기준 오름차순 정렬

이렇게 쿼리를 작성했습니다!

 

# [ 2안 쿼리 작성 설명 ]

2안의 쿼리는 CASE WHEN 문을 통해 범주화를 직접 해줬습니다.

 

지금 문제에서는 PRICE의 최댓값을 조회하니 85000원이었기 때문에

하나하나 직접 범주화를 해서 때문에 작성할 수 있었지만,

 

PRICE의 범위가 0원부터 30만원과 같이 범위가 넓은 경우에는

이러한 코드는 매우 비효율적이기 때문에 권장하지 않아요!

 

따라서 설명도 따로 하지 않을게요!

CASE WHEN문을 미리 본다고 생각만 하시면 될것 같아요! :)

(CASE WHEN 문도 조만간 문제로 다룰 예정입니다!)


4. 데코의 문제 풀이 후기

이번 문제는 특정 컬럼을 이용하여 범주화하고 이를 집계하는 문제예요!

 

'PRICE' 컬럼을 만원 단위로 범주화하는 것이 포인트 같아요!

저는 FLOOR() 함수를 이용해서 소수를 버리는 코드를 작성했어요!

 

SQL에서 FLOOR() 함수는 소수를 모두 버리는 함수입니다!

소수점 관련 함수에는 아래와 같이 총 4개가 존재하는데, 주어진 상황에 맞게 사용하면 될 것 같아요!

  • ROUND() 
  • CEIL()
  • FLOOR()
  • TRUNCATE()

아래에서 소수점을 다루는 함수의 설명과 예를 들어볼게요!

 

1. ROUND()

-  ROUND(값, 자릿수) 

-  '자릿수'까지 나타나도록 반올림을 진행합니다.
자릿수를 정의하지 않으면, 소수점 첫 번째 위치에서 반올림을 합니다.

SELECT  ROUND( 1.678, 2) 
출력 결과 : 1.68

SELECT  ROUND( 1.678 ) 
출력 결과 : 2

2. CEIL()

-  CEIL(값)

-  소수점 값의 상관없이 올림을 진행합니다.

SELECT  CEIL1.123
출력 결과 : 2

SELECT  CEIL1.678 
출력 결과 : 2

3. FLOOR()

-  FLOOR(값)

-  소수점 값의 상관없이 내림을 진행합니다.

SELECT  FLOOR1.123 
출력 결과 : 1

SELECT  FLOOR1.678 
출력 결과 : 1

4. TRUNCATE()

TRUNCATE(값, 자릿수)

-  '자릿수'까지 나타나도록 내림을 진행합니다.

ROUND() 함수와 다르게 자릿수를 명시하지 않으면 오류가 발생합니다!

SELECT  TRUNCATE( 1.678, 2) 
출력 결과 : 1.67

SELECT  TRUNCATE1.678 
출력 결과 : ERROR

소수점 관련 함수들에 대해 이해가 가셨나요?

 

보통 ROUND() 함수를 가장 많이 사용하는데, 이번 문제와 같이 분석 요구사항에 맞게 소주점 관련 함수들을 이용해주시면 될 것 같아요!

 

이번 문제는 특정 컬럼을 이용하여 범주화하고 이를 집계하는 문제를 풀어봤습니다!

 

설명이 어려운 부분 혹은 잘 이해가 안 가는 부분은 그리고 더 궁금한 내용이 있다면

언제든지 댓글로 남겨주세요!
빠르게 궁금증을 해결해드릴게요!

공감과 댓글은 큰 힘이 됩니다!
읽어주셔서 감사해요!

 

또 다른 SQL 문제로 찾아뵐게요!

 

LIST