sql sum 과 case 사용하기

조건에 맞는 값을 합친다. sum 과 case

  • select 절에서 sum과 case를 활용하여 데이터를 유용하게 조작할 수 있다.
  • 대체로 데이터를 단순화한다. sum은 하나의 숫자로 반환하고 case는 몇 가지 상태값으로 변환한다.
  • group by를 활용하여 그룹별 조회로 활용할 수 있다.

문제 Capital Gain/Loss

  • https://leetcode.com/problems/capital-gainloss/
  • Stocks 테이블에는 주식의 이름, 구매 및 판매 여부, 값이 있다. 주식 종류 마다 구매와 판매의 가격을 비교하여 최종적인 수익을 구한다.
Input: 
Stocks table:
+---------------+-----------+---------------+--------+
| stock_name    | operation | operation_day | price  |
+---------------+-----------+---------------+--------+
| Leetcode      | Buy       | 1             | 1000   |
| Corona Masks  | Buy       | 2             | 10     |
| Leetcode      | Sell      | 5             | 9000   |
| Handbags      | Buy       | 17            | 30000  |
| Corona Masks  | Sell      | 3             | 1010   |
| Corona Masks  | Buy       | 4             | 1000   |
| Corona Masks  | Sell      | 5             | 500    |
| Corona Masks  | Buy       | 6             | 1000   |
| Handbags      | Sell      | 29            | 7000   |
| Corona Masks  | Sell      | 10            | 10000  |
+---------------+-----------+---------------+--------+
Output: 
+---------------+-------------------+
| stock_name    | capital_gain_loss |
+---------------+-------------------+
| Corona Masks  | 9500              |
| Leetcode      | 8000              |
| Handbags      | -23000            |
+---------------+-------------------+

문제의 해소

  • 주식의 종류를 기준으로 group by 를 한다.
  • 주식을 구매했을 때 빼기를 하고 주식을 팔 때 더하기를 한다. 그 합을 구한다.

쿼리

select 
    stock_name
    , sum(case when operation='buy' then -price
         else price
          end) as 'capital_gain_loss'
from stocks
group by stock_name

가장 높은 비율을 가진 데이터 뽑기 Get Highest Answer Rate Question

  • https://leetcode.com/problems/get-highest-answer-rate-question/
  • 특정 문제가 있고 그것을 보여(show)준다. 상대방은 대답(answer)하거나 무시(skip)한다. 각 문제마다 대답의 비율을 구하고 가장 대답의 비율이 높은 문제를 출력한다. 대답의 비율이 동일하면 그 중 가장 빠른 id를 출력한다.
Input: 
SurveyLog table:
+----+--------+-------------+-----------+-------+-----------+
| id | action | question_id | answer_id | q_num | timestamp |
+----+--------+-------------+-----------+-------+-----------+
| 5  | show   | 285         | null      | 1     | 123       |
| 5  | answer | 285         | 124124    | 1     | 124       |
| 5  | show   | 369         | null      | 2     | 125       |
| 5  | skip   | 369         | null      | 2     | 126       |
+----+--------+-------------+-----------+-------+-----------+
Output: 
+------------+
| survey_log |
+------------+
| 285        |
+------------+

문제의 해소

  • 이 문제는 사실상 answer / show를 구하는 문제이다.

쿼리

select 
  question_id survey_log
from (
  select 
    question_id
    , sum(case when action = 'answer' then 1 else 0 end)/ sum(case when action = 'show' then 1 else 0 end) rt
  from surveylog 
  group by question_id 
    ) tb 
order by tb.rt desc, tb.question_id asc 
limit 1

기타

  • if, ifnull 등 case when과 유사한 문법이 존재한다.