BananMoon / SQL-Practice

It is Study Place to practice SQL.
0 stars 0 forks source link

조건문 쓰기 CASE + HackerRank 문제풀이 #3

Open BananMoon opened 4 months ago

BananMoon commented 4 months ago

조건문쓰기 CASE

문법

CASE 
    WHEN {조건절} THEN {표시할 값}
    WHEN {조건절} THEN {표시할 값}
    ELSE
END

예제

SELECT CASE
    WHEN categoryid = 1 AND supplierid = 1 THEN 'Drink'
    WHEN categoryid = 2 THEN 'Condiment'
    ELSE 'Etc'
END AS 'categoryName', categoryid, supplierid
FROM Products

CASE 문과 GROUP BY

CASE 문 처리한 값을 GROUP BY 절에서 사용할 수 있다.

Ex) 전체 카테고리의 평균은 궁금하지 않고, 내가 지정한 데이터들에 대한 평균을 구하고 싶다면?? 원하는 조건 절로 CASE 문을 만들고, 그러헥 만들어진 데이터를 Alias로 표현하고, Alias 값을 이용하여 GROUP BY 를 진행한다.

SELECT CASE
    WHEN categoryid = 1 AND supplierid = 1 THEN 'Drink'
    WHEN categoryid = 2 THEN 'Source'
    ELSE 'Etc'
END AS 'new_category', AVG(price)
FROM Products
GROUP BY new_category

CASE문을 통해 카테고리 별 평균 값 구할 수 있다.

카테고리 1번인 데이터만 price 출력. 그외는 NULL 출력

SELECT CASE WHEN category = 1 THEN price ELS null END
FROM Products; 

카테고리 1번인 데이터의 평균 값 : 위에서 구한 값에 AVG() 적용

SELECT AVG(CASE WHEN category = 1 THEN price ELSE null END)
FROM Products; 

테이블 피봇팅

카테고리 1, 2, 3번을 가로로 출력하고자 한다면?

테이블 피봇팅 을 이용한다 !

아래와 같이 세로로 출력되는 테이블을 가로로 출력하면, categoryId AVG(price)
1 3.5
2 70.9

아래와 같다.

categoryId1_avg categoryId2_avg categoryId3_avg
3.5 70.9 80
SELECT AVG(CASE WHEN category = 1 THEN price ELSE null END) AS 'categoryId1_avg'
             , AVG(CASE WHEN category = 2 THEN price ELSE null END) AS 'categoryId2_avg'
             , AVG(CASE WHEN category = 3 THEN price ELSE null END) AS 'categoryId3_avg'
FROM Products; 
BananMoon commented 4 months ago
  1. Type of Triangle

SQL문

MySQL

SELECT 
    CASE 
        WHEN A = B AND B = C AND A + B > C THEN 'Equilateral'
        WHEN (A = B OR B = C OR A = C) AND (A + B > C) THEN 'Isosceles'
        WHEN A != B AND B != C AND A != C AND A + B > C THEN 'Scalene'
        WHEN A + B <= C THEN  'Not A Triangle'
END
FROM TRIANGLES;

개선

  1. WHEN 절의 순서가 중요하다! 작성한 WHEN절 순서대로 고려하므로 우선순위를 높여야 하는 것을 앞에 둔다. Ex1) 만약 정삼각형인지 고려하는 WHEN 절보다 이등분 삼각형인지 고려하는 WHEN 절을 먼저 두게 되면 이등분 삼각형은 정삼각형으로 출력된다. Ex2) 만약 이등분 삼각형이든, 삼각형이 아닌 길이 (A + B <= C)에 성립한다면 삼각형이 아니라고 출력하려면 해당 케이스를 먼저 앞에 둔다.

2.어떤 칼럼이든 두개의 길이를 더한게 한개의 길이보다 길어야 하므로 A+B<=C 케이스 외 케이스인 A+C<=B, B+C<=A 케이스도 같이 적어준다.

  1. 마지막 케이스인 'Scalence'는 사실 ELSE로 주어도 통과한다.
    SELECT 
    CASE 
        WHEN A = B AND B = C THEN 'Equilateral' -- Ex1
        WHEN A + B <= C OR A + C <= B OR A + C <= B THEN  'Not A Triangle'  -- Ex2
        WHEN A = B OR B = C OR A = C THEN 'Isosceles'
        WHEN A != B AND B != C AND A != C THEN 'Scalene'
    END
    FROM TRIANGLES;
BananMoon commented 4 months ago
  1. 1179. Reformat Department Table

문제 풀기 실패

고려해야할 사항

테이블 구조 바꾸는 작업 : 테이블 피봇팅 작업 필요!

  1. month 별 값을 구하고 month들을 가로 줄로 나타내야하므로 피봇팅해야 한다.
  2. CASE 문을 이용해서 month 별 revenue 값을 거르고 SUM()을 수행한다.
    • SELECT SUM(CASE WHEN month = 'Jan' THEN revenue ELSE NULL END) AS Jan_Revenue;를 수행해보면 Jan_Revenue 칼럼 한개가 출력되는 것을 확인한다.
    • 이러한 칼럼을 month 별로 가로로 줄세워야 하므로 동일한 SUM()을 12개 작성한다.
  3. 각 부서 별로 month를 구하는 것이니 부서 id 값이 중복되지 않게 row가 출력되어야 한다. 이를 위해 GROUP BY를 수행한다.
SELECT id
     , SUM(CASE WHEN month = 'Jan' THEN revenue ELSE NULL END) AS Jan_Revenue
     , SUM(CASE WHEN month = 'Feb' THEN revenue ELSE NULL END) AS Feb_Revenue
     , SUM(CASE WHEN month = 'Mar' THEN revenue ELSE NULL END) AS Mar_Revenue
     , SUM(CASE WHEN month = 'Apr' THEN revenue ELSE NULL END) AS Apr_Revenue
     , SUM(CASE WHEN month = 'May' THEN revenue ELSE NULL END) AS May_Revenue
     , SUM(CASE WHEN month = 'Jun' THEN revenue ELSE NULL END) AS Jun_Revenue
     , SUM(CASE WHEN month = 'Jul' THEN revenue ELSE NULL END) AS Jul_Revenue
     , SUM(CASE WHEN month = 'Aug' THEN revenue ELSE NULL END) AS Aug_Revenue
     , SUM(CASE WHEN month = 'Sep' THEN revenue ELSE NULL END) AS Sep_Revenue
     , SUM(CASE WHEN month = 'Oct' THEN revenue ELSE NULL END) AS Oct_Revenue
     , SUM(CASE WHEN month = 'Nov' THEN revenue ELSE NULL END) AS Nov_Revenue
     , SUM(CASE WHEN month = 'Dec' THEN revenue ELSE NULL END) AS Dec_Revenue
FROM department
GROUP BY id;