본문 바로가기

Database/DB

LeetCode sql 문제, 유저별 월별 집계

https://leetcode.com/problems/reformat-department-table/

 

Reformat Department Table - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

쉬운 문제인데, 푸는데 너무 오래 걸렸다. sql은 언제나 수행이 부족하다.

아래와 같이 테이블이 있을 때

Department table:
+------+---------+-------+
| id   | revenue | month |
+------+---------+-------+
| 1    | 8000    | Jan   |
| 2    | 9000    | Jan   |
| 3    | 10000   | Feb   |
| 1    | 7000    | Feb   |
| 1    | 6000    | Mar   |
+------+---------+-------+

 

id 별 1월~12월까지로 표현하는 방식이다.

Result table:
+------+-------------+-------------+-------------+-----+-------------+
| id   | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |
+------+-------------+-------------+-------------+-----+-------------+
| 1    | 8000        | 7000        | 6000        | ... | null        |
| 2    | 9000        | null        | null        | ... | null        |
| 3    | null        | 10000       | null        | ... | null        |
+------+-------------+-------------+-------------+-----+-------------+

 

처음엔 group by 만 하면 쉽게 끝날 줄 알았는데,

1. 새로운 칼럼을 만들어서 표현해야 한다.

2. 데이터는 id로 group by 가 되어야 한다.

라는 조건이 주어졌다.

 

 

나의 풀이 (속도가 5%나왔다....)

# Write your MySQL query statement below
select id,  
 max(if( month ='Jan',  revenue, null)) as 'Jan_Revenue',
 max(if( month ='Feb',  revenue, null)) as 'Feb_Revenue',
 max(if( month ='Mar',  revenue, null)) as 'Mar_Revenue',
 max(if( month ='Apr',  revenue, null)) as 'Apr_Revenue',
 max(if( month ='May',  revenue, null)) as 'May_Revenue',
 max(if( month ='Jun',  revenue, null)) as 'Jun_Revenue',
 max(if( month ='Jul',  revenue, null)) as 'Jul_Revenue',
 max(if( month ='Aug',  revenue, null)) as 'Aug_Revenue',
 max(if( month ='Sep',  revenue, null)) as 'Sep_Revenue',
 max(if( month ='Oct',  revenue, null)) as 'Oct_Revenue',
 max(if( month ='Nov',  revenue, null)) as 'Nov_Revenue',
 max(if( month ='Dec',  revenue, null)) as 'Dec_Revenue'
from Department
group by id
    

근데, 다른 사람들의 풀이과정도 모두 같았다... 어?

 

 

번외 1.

답변 중에서 재미있는 글이 있었는데,

case when // if 문중에 무엇을 써야 하냐는 것이었다.

답변으로 아래 링크가 달렸는데,

https://stackoverflow.com/questions/2429226/case-statements-versus-coded-if-statements

 

Case Statements versus coded if statements

What is more efficient - handling with case statements in sql or handling the same data using if statements in code. I'm asking because my colleague has a huge query that has many case statements. I

stackoverflow.com

 

case // if는 실제 성능상에도 별 차이가 없기 때문에 아무거나 사용해도 된다.

SELECT
    SUM(CASE WHEN PaidStatus = 0 THEN Amount ELSE 0 END) AS TotalUnpaid,
    SUM(CASE WHEN PaidStatus = 1 THEN Amount ELSE 0 END) AS TotalPaid
FROM ...

쿼리문이 위와 같을 경우 UI단에서 하는 경우도 많이 있는데(PaidStatus의 값에 따른 분기문) sql이 성능상 훨씬 이득이기 때문에 이러한 작업은 DB 단에서 처리해야 한다는 글이었다.

 

  10년 전의 답글이라 현재의 생태계에 맞지 않는 답변이었다. 오늘의 서비스에서는 대부분의 비즈니스 로직이 오히려 클라이언트단으로 이동하였다. JS//브라우저의 성능 향상과 통신속도 및 개인의 컴퓨터 자원을 충분히 활용하고도 남기 때문이다. 이 모든 비즈니스 로직을 서버단에서 처리한다면 감당이 안 되는 현실이 되었다. 불과 10년 만에 시스템의 발단이 많은 것을 변화시킨 것을 느끼게 한 재미있는 글이었다.

 

번외 2.

일반적인 언어에서의 case // if 문의 성능 차이는 없다. (jump table도 컴파일러 최적화마다 달리 적용된다. )

성능 생각하기 전에 보기 좋은 코드를 만들자.

'Database > DB' 카테고리의 다른 글

파티션 개념  (0) 2021.06.21
객체 지향 데이터베이스 (OODB / object-oriented Database)  (2) 2021.06.18
postGIS 쿼리 튜닝  (0) 2021.04.24
postgreSQL core  (2) 2020.06.15
DBMS core architecture 2  (0) 2020.06.14