sql, 가상의 column을 사용하기

column 을 추가하여 비교하기

  • 요구사항을 이행할 때, where 절이나 group by 절을 사용하는 것보다, 칼럼 하나가 추가된 임시 테이블을 만들어서 해결하는 것이 더 빠른 경우가 있다.

문제

  • https://leetcode.com/problems/drop-type-1-orders-for-customers-with-type-0-orders/
  • Orders 테이블이 있다. customer_id는 order_type을 0이나 1을 가질 수 있다. 만약 0을 가진다면 1을 출력해서는 안된다.
Input: 
Orders table:
+----------+-------------+------------+
| order_id | customer_id | order_type |
+----------+-------------+------------+
| 1        | 1           | 0          |
| 2        | 1           | 0          |
| 11       | 2           | 0          |
| 12       | 2           | 1          |
| 21       | 3           | 1          |
| 22       | 3           | 0          |
| 31       | 4           | 1          |
| 32       | 4           | 1          |
+----------+-------------+------------+
Output: 
+----------+-------------+------------+
| order_id | customer_id | order_type |
+----------+-------------+------------+
| 31       | 4           | 1          |
| 32       | 4           | 1          |
| 1        | 1           | 0          |
| 2        | 1           | 0          |
| 11       | 2           | 0          |
| 22       | 3           | 0          |
+----------+-------------+------------+

문제 해소의 방향

  • order_type이 0인 경우는 모두 출력을 하면 된다.
  • order_type이 1인 경우 출력하거나 하지 말아야 한다. 이를 판별해야 한다.
  • 기존 테이블에 하나의 칼럼을 추가하는 방식으로 문제를 해소하였다. 각 레코드 마다 해당 회원이 order_type을 1을 가지고 있는지의 여부를 보여주면 된다. 그러면 아래와 같은 테이블이 생성된다.
+----------+-------------+------------+----------------------+
| order_id | customer_id | order_type |o2_order_type         |
+----------+-------------+------------+----------------------+
| 1        | 1           | 0          |true                  |
| 2        | 1           | 0          |true                  |
| 11       | 2           | 0          |true                  |
| 12       | 2           | 1          |true                  |
| 21       | 3           | 1          |true                  |
| 22       | 3           | 0          |true                  |
| 31       | 4           | 1          |false                 |
| 32       | 4           | 1          |false                 |
+----------+-------------+------------+----------------------+

쿼리

  • 위의 레코드 추가는 join으로 하였다.
  • 다만, o2_order_type은 위의 예시와 다르게 null이 가능하다. left join이기 때문이다.
select distinct
    tb.order_id 
    , tb.customer_id 
    , tb.order_type
from(
    select 
        o1.order_id 
        , o1.customer_id
        , o1.order_type
        , o2.order_type o2_order_type
    from orders o1
    left join orders o2
    on o2.customer_id = o1.customer_id and o2.order_type = 0
) tb 
where tb.order_type = 0
      or (tb.order_type = 1 and tb.o2_order_type is null)