프로그래머스/My SQL

💫대장균의 크기에 따라 분류하기 2

싱싱한복초이 2024. 12. 13. 10:07

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

 

프로그래머스

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

programmers.co.kr

[문제]

대장균 개체의 크기를 내름차순으로 정렬했을 때 상위 0% ~ 25% 를 'CRITICAL', 26% ~ 50% 를 'HIGH', 51% ~ 75% 를 'MEDIUM', 76% ~ 100% 를 'LOW' 라고 분류합니다. 대장균 개체의 ID(ID) 와 분류된 이름(COLONY_NAME)을 출력하는 SQL 문을 작성해주세요. 이때 결과는 개체의 ID 에 대해 오름차순 정렬해주세요 . 단, 총 데이터의 수는 4의 배수이며 같은 사이즈의 대장균 개체가 서로 다른 이름으로 분류되는 경우는 없습니다.

 

[나의 풀이]

WITH O AS (
SELECT ID, SIZE_OF_COLONY, 
       NTILE(4) OVER (ORDER BY SIZE_OF_COLONY DESC) AS QUARTILE
FROM ECOLI_DATA
)

SELECT 
ID, 
CASE 
    WHEN QUARTILE = 1 THEN 'CRITICAL'
    WHEN QUARTILE = 2 THEN 'HIGH'
    WHEN QUARTILE = 3 THEN 'MEDIUM'
    WHEN QUARTILE = 4 THEN 'LOW'
END AS COLONY_NAME
FROM O
ORDER BY ID;

 

[다른 풀이]

1)

SELECT ID,
CASE
    WHEN PER <= 0.25 THEN 'CRITICAL'
    WHEN PER <= 0.5 THEN 'HIGH'
    WHEN PER <= 0.75 THEN 'MEDIUM'
    ELSE 'LOW'
END AS COLONY_NAME
FROM(
    SELECT ID,
    PERCENT_RANK() OVER (ORDER BY SIZE_OF_COLONY DESC) AS PER
    FROM ECOLI_DATA
) A
ORDER BY ID;

PERCENT_RANK(): 행의 백분율 순위를 계산하며 0~1의 값을 갖는다

 

TEST1 예시)

SELECT ID, SIZE_OF_COLONY
FROM ECOLI_DATA
ORDER BY SIZE_OF_COLONY;

SELECT ID,
PERCENT_RANK() OVER (ORDER BY SIZE_OF_COLONY DESC) AS PER
FROM ECOLI_DATA;

 

2)

SELECT D.ID,
      CASE
        WHEN D.R > D.MAX_ID*0.75 THEN 'CRITICAL'
        WHEN D.R > D.MAX_ID*0.5 THEN 'HIGH'
        WHEN D.R > D.MAX_ID*0.25 THEN 'MEDIUM'
        ELSE 'LOW'
      END AS COLONY_NAME
FROM (
    SELECT ID,
    	# 순위
        ROW_NUMBER() OVER (ORDER BY SIZE_OF_COLONY) AS R,
        # 총 데이터의 수
        MAX(ID) OVER() AS MAX_ID
    FROM ECOLI_DATA
) D
ORDER BY D.ID;

 

3)

SELECT 
    A.ID,
    CASE 
        WHEN A.RANKING / A.TOTAL_COUNT * 100 <= 25 THEN 'CRITICAL'
        WHEN A.RANKING / A.TOTAL_COUNT * 100 <= 50 THEN 'HIGH'
        WHEN A.RANKING / A.TOTAL_COUNT * 100 <= 75 THEN 'MEDIUM'
        ELSE 'LOW'
    END AS 'COLONY_NAME'
FROM 
    (SELECT    
        ID,  
        RANK() OVER (ORDER BY SIZE_OF_COLONY DESC) AS RANKING, 
        COUNT(*) OVER () AS TOTAL_COUNT
    FROM ECOLI_DATA) AS A
ORDER BY A.ID;
SELECT    
    ID,  
    RANK() OVER (ORDER BY SIZE_OF_COLONY DESC) AS RANKING, 
    COUNT(*) OVER () AS TOTAL_COUNT
FROM ECOLI_DATA);