https://leetcode.com/problems/customer-who-visited-but-did-not-make-any-transactions/description/?envType=study-plan-v2&envId=top-sql-50

코드설명

NOT EXISTS + LEFT OUTER JOIN + GROUP BY + IS NULL + COUNT 을 활용합니다.

 

고객 중 방문해서 한번도 구매하지 않은 고객을 구해야 합니다.

두가지 방법이 존재합니다.

1. NOT EXISTS 를 활용하여 부분범위처리가 가능한 쿼리 -> 하지만 이 방법의 경우 Transaction 테이블이 많아지면 많아질수록 안좋아짐.

2. LEFT OUTER JOIN 을 활용하여 배치쿼리에 유리한 쿼리

 

1번쨰 방법의 경우, NOT EXISTS 쿼리로 만약 Transaction 중 한번이라도 존재한다면 종료합니다.

그런뒤에, GROUP BY 로 각 쿼리를 묶으면 되겠지요.

 

2번쨰 방법의 경우, LEFT OUTER JOIN을 통해 방문했지만, 구입하지 않은경우 Transaction의 T_ID가 NULL로 나온다는 것을 활용합니다. 그떄 T_ID가 NULL이라면 필터링하는  쿼리를 통해, 오직 한번이상 방문했는데 구매하지 않은 사람의 목록이 나옵니다.

 

주어진 문제의 Entity 관계를 분석해보면, 

Visit과 Transaction의 관계차수 = 1:N 관계,

주인관계 = (주인 : 자식),

참여특성 = (필수 : 선택) 관계입니다.

MYSQL 코드

정답코드1입니다.

SELECT V.CUSTOMER_ID AS customer_id
    , COUNT(V.VISIT_ID) AS COUNT_NO_TRANS
FROM VISITS V
WHERE NOT EXISTS (SELECT 'X'
                FROM TRANSACTIONS T
                WHERE T.VISIT_ID = V.VISIT_ID)
GROUP BY CUSTOMER_ID

 

정답코드2입니다.

SELECT V.CUSTOMER_ID AS customer_id, COUNT(V.VISIT_ID) AS count_no_trans
FROM VISITS V
LEFT OUTER JOIN TRANSACTIONS T
ON V.VISIT_ID = T.VISIT_ID
WHERE T.TRANSACTION_ID IS NULL
GROUP BY V.CUSTOMER_ID

 

LEFT OUTER JOIN은 SCALAR SUBQUERY 로 대체할 수 있는 가능성이 있어서 확인했지만, 이 경우 1:N 관계를 가지고있어 처리가 불가능합니다.

+ Recent posts