코드설명
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 관계를 가지고있어 처리가 불가능합니다.