해결된 질문
작성
·
419
4
안녕하세요-
리트코드 1179 Reformat Department Table 문제 풀이에서
SUM() 을 왜 사용하는건가요? ㅠ.ㅠ
선생님 해설 이전에 sum 을 사용하지 않고 코드를 실행했더니 jan 값이 두개가 null 이 출력되면서 오답이라고 떴는데,
여기서 왜 SUM 함수를 사용해야 제대로된값이 출력되는지 흐름이 이해가안됩니다 ㅠ_ㅠ
답변 5
3
CASE 의 속성과 GROUP BY 의 속성을 따로 이해하면 좋을 것 같아요.
CASE는 데이터를 순서대로 조회하면서, IF 조건에 맞는다면 THEN 뒤의 값을 넣고, 그렇지 않으면 ELSE 값을 넣는 역할을 수행해요. 그래서 맨 먼저 아래 쿼리를 실행해서 CASE의 아웃풋이 어떻게 나오는지 확인을 해보셨으면 좋겠어요.
SELECT id
, CASE WHEN month = 'Jan' THEN revenue ELSE NULL END AS Jan_Revenue
, month
, revenue
FROM DEPARTMENT
부서 id가 어떤 값을 가지든지 상관 없이 month = 'Jan' 이라면 revenue를 넣어주고, 그렇지 않으면 NULL 값을 넣기 때문에 아래와 같이 아웃풋이 나올거예요.
id Jan_Revenue month revenue
1 8000 "Jan" 8000
1 null "Feb" 7000
1 null "Mar" 6000
여기에서 두번째 그리고 세 번째 행은 부서 id는 1번이지만, month가 "Jan"이 아니기 때문에 7000, 6000인 revenue 값 대신 CASE 문을 통해 null로 표현을 해줬죠. 여기에서 GROUP BY를 id를 기준으로 수행해준다면 어떤 결과가 나올까요?
SELECT id
, SUM(CASE WHEN month = 'Jan' THEN revenue ELSE NULL END) AS example
FROM DEPARTMENT
GROUP BY id
라고 한다면, 8000, null, null 값들 중 SUM() 함수는 null을 무시하므로 최종적인 값은 아래와 같이 나올거예요
id example
1 8000
이렇게 CASE 문은 month = 'Jan' 에 해당되지 않는 값들을 null로 표시하고, SUM(), AVG() 같은 집계함수는 null 들을 무시하고 연산을 수행하면서 결국 id, month 조건에 딱 맞는 값만 출력되게 한다고 역할을 나누어서 생각하시면 좋을 것 같네요 :) 답변이 도움이 되었으면 좋겠네요. SQL을 오래 사용하신 분들도 잘 헷갈려하는 파트니까 곰곰히 하나씩 뜯어가면서 쿼리 실행해보고 감을 잡으셨으면해요.
0
다른 분의 질문에 죄송합니다. 저도 비슷한 궁금증이 있었는데 덕분에 해결되었어요! 그런데 추가질문이 있어 이렇게 글을 남깁니다 ㅠㅠ
제가 느끼기로는 mysql 자체에서 GROUP BY를 실행할 경우, 한 카테고리에 여러 값이 있을 때 맨 위의 값만 출력하는 경우가 종종 있는 것 같더라고요.
예를 들어 해당 문제에서, id로 GROUP BY를 실행할 경우 단순히 revenue와 month를 출력하라고 명령했을 때 맨 위의 revenue 8000, month Jan만 출력합니다.
SELECT id,revenue,month
FROM DEPARTMENT
GROUP BY id
이 경우 출력되는 값은
{"headers": ["id", "revenue", "month"], "values": [[1, 8000, "Jan"], [2, 9000, "Jan"], [3, 10000, "Feb"]]}
이렇게요.
그러니까 id =1 인 revenue 7000 month Feb나 revenue 6000 month Mar는 아예 출력되지 않는 것 같습니다.
이게 인터프리터 오류인지 혹은 원래 그렇게 설계된 것인지는 모르겠으나, 이러한 현상이 다른 때에도 종종 발생하는 경우를 접했습니다.
어쨌든 이러한 현상 때문에 SUM과 같은 집계함수를 해야하는 것 같는데, 혹시 맞나요?
아까의 예를 다시 설명하자면, 아까와 같은 코드로 하되 revenue가 아닌 SUM(revenue)를 출력하면
{"headers": ["id", "SUM(revenue)", "month"], "values": [[1, 21000, "Jan"], [2, 9000, "Jan"], [3, 10000, "Feb"]]}
이렇게 정상적으로 전체 revenue 값이 출력되는 것처럼요.
정리하자면
GROUP BY 함수를 사용할 때 맨 위의 데이터만 출력하는 현상이 존재하고, 집계함수를 사용하여 데이터를 전체적으로(?) 한번 더 읽어주는 것이 맞나요?
또 이걸 작성하면서 생긴 궁금증인데..
SELECT문에서
CASE WHEN month='Jan' THEN revenue ELSE NULL END 을 사용함으로써
ID로 GROUP BY된 테이블 속 Jan가 아닌 데이터들의 revenue 값이 다 NULL로 표시하는데요,
이는 원래의 department 자체를 변화시키는 건 아닌거죠?
raw data를 가져오기만 하는 것이 맞나요?
0
0
넵
에러가 날때의 SQL 코드 (오답 코드)
SELECT id
, CASE WHEN month = 'Jan' THEN revenue ELSE NULL END AS Jan_Revenue
, CASE WHEN month = 'Feb' THEN revenue ELSE NULL END AS Feb_Revenue
, CASE WHEN month = 'Mar' THEN revenue ELSE NULL END AS Mar_Revenue
, CASE WHEN month = 'Apr' THEN revenue ELSE NULL END AS Apr_Revenue
, CASE WHEN month = 'May' THEN revenue ELSE NULL END AS May_Revenue
, CASE WHEN month = 'Jun' THEN revenue ELSE NULL END AS Jun_Revenue
, CASE WHEN month = 'Jul' THEN revenue ELSE NULL END AS Jul_Revenue
, CASE WHEN month = 'Aug' THEN revenue ELSE NULL END AS Aug_Revenue
, CASE WHEN month = 'Sep' THEN revenue ELSE NULL END AS Sep_Revenue
, CASE WHEN month = 'Oct' THEN revenue ELSE NULL END AS Oct_Revenue
, CASE WHEN month = 'Nov' THEN revenue ELSE NULL END AS Nov_Revenue
, CASE WHEN month = 'Dec' THEN revenue ELSE NULL END AS Dec_Revenue
FROM DEPARTMENT
GROUP BY id
----- 위 SQL문 Output
{
"headers": ["id", "Jan_Revenue", "Feb_Revenue", "Mar_Revenue", "Apr_Revenue", "May_Revenue", "Jun_Revenue", "Jul_Revenue", "Aug_Revenue", "Sep_Revenue", "Oct_Revenue", "Nov_Revenue", "Dec_Revenue"],
"values": [
[1, 8000, null, null, null, null, null, null, null, null, null, null, null],
[2, 9000, null, null, null, null, null, null, null, null, null, null, null],
[3, null, 10000, null, null, null, null, null, null, null, null, null, null]
]}
-------
------ Expected
{
"headers": ["id", "Jan_Revenue", "Feb_Revenue", "Mar_Revenue", "Apr_Revenue", "May_Revenue", "Jun_Revenue", "Jul_Revenue", "Aug_Revenue", "Sep_Revenue", "Oct_Revenue", "Nov_Revenue", "Dec_Revenue"],
"values": [
[1, 8000, 7000, 6000, null, null, null, null, null, null, null, null, null],
[2, 9000, null, null, null, null, null, null, null, null, null, null, null],
[3, null, 10000, null, null, null, null, null, null, null, null, null, null]]
}
위 결과물처럼 1번 Row 의 revenue 2번, 3번 값이 7000, 6000 이 들어가는게 아닌
null 이 들어갑니다,
해서 선생님 해설대로 SUM 으로 감싸주었을때는 null 이 아니라 7000,6000 이 출력되면서 정답처리 되는데요!
여기서 어려운것이..
저는 시나리오를 아래처럼 생각했는데,
Table의 모든 행을
CASE WHEN month = 'Jan' THEN revenue ELSE NULL END AS Jan_Revenue 문으로 돌면서,
month 가 Jan 인 Revenue 값을 가져오기 때문에, 별도의 SUM 함수가 없어도 알아서 7000, 6000 의 값이 들어갈것이다
그런데 첫번째 값인 8000 을 제외하고는 왜 null이 들어가고,
이걸 해결하기 위해 왜 SUM(), MAX() 등의 함수로 처리해야 하는지 이해가 어렵습니다 ㅠ
-- 이하 문제에서의 Table
Department table: +------+---------+-------+ | id | revenue | month | +------+---------+-------+ | 1 | 8000 | Jan | | 2 | 9000 | Jan | | 3 | 10000 | Feb | | 1 | 7000 | Feb | | 1 | 6000 | Mar | +------+---------+-------+
0
가빈님, 안녕하세요! 테이블 피봇 문제가 원래 좀 어려워요ㅎㅎ
근데 제가 가빈님이 어떤 코드를 작성했을 때에 어떤 에러가 났는지 알 수가 없어서 혹시 에러가 날 때의 SQL 코드와, 결과값을 올려주실 수 있을까요? 그리고 그 코드가 어떤 결과를 출력할거라고 예상하셨는지 예상 output도 같이 적어주시면 좋겠어요.