BAD: 단일 주문 정상 / 복수 주문 오류
다중행을 반환하는 스칼라 서브쿼리
① 주문 1건인 회원(정상 실행됨)
SELECT m.mbr_id
,(
SELECT o.ord_amt
FROM startdbpg.tr_ord_big o
WHERE o.mbr_id = m.mbr_id
AND o.ord_dtm >= '2024-01-01'
AND o.ord_dtm < '2024-01-02'
) AS ord_amt
FROM startdbpg.ms_mbr_big m
WHERE m.mbr_id = 'M00007'
;
SQL
복사
실행 결과 보기
② 주문 2건인 회원(에러)
SELECT m.mbr_id
,(
SELECT o.ord_amt
FROM startdbpg.tr_ord_big o
WHERE o.mbr_id = m.mbr_id
AND o.ord_dtm >= '2024-01-01'
AND o.ord_dtm < '2024-01-02'
) AS ord_amt
FROM startdbpg.ms_mbr_big m
WHERE m.mbr_id = 'M00051'
;
SQL
복사
실행 결과 보기
•
같은 회원·일자의 주문이 1건이면 정상이고, 2건이면 에러가 납니다.
•
테스트 데이터에서는 1건이라 통과했다가, 운영에서 주문이 2건인 회원이 생기는 순간 SQL 전체가 실패합니다.
GOOD: 두 회원 모두 1 rows(정상)
집계하여 단일값 반환
① 주문 1건인 회원(정상)
SELECT m.mbr_id
,(
SELECT SUM(o.ord_amt)
FROM startdbpg.tr_ord_big o
WHERE o.mbr_id = m.mbr_id
AND o.ord_dtm >= '2024-01-01'
AND o.ord_dtm < '2024-01-02'
) AS ord_amt
FROM startdbpg.ms_mbr_big m
WHERE m.mbr_id = 'M00007'
;
SQL
복사
실행 결과 보기
② 주문 2건인 회원(정상)
SELECT m.mbr_id
,(
SELECT SUM(o.ord_amt)
FROM startdbpg.tr_ord_big o
WHERE o.mbr_id = m.mbr_id
AND o.ord_dtm >= '2024-01-01'
AND o.ord_dtm < '2024-01-02'
) AS ord_amt
FROM startdbpg.ms_mbr_big m
WHERE m.mbr_id = 'M00051'
;
SQL
복사
실행 결과 보기
•
합계가 필요하면 SUM으로 집계합니다.
•
최신 1건이 필요하면 ORDER BY ord_dtm DESC, ord_no DESC LIMIT 1처럼 정렬 후 1건을 고릅니다.
•
조건이 PK로 정확히 들어가 1건이 보장되면 집계나 정렬은 필요 없습니다.
KEY POINT
•
스칼라 서브쿼리는 한 행만 반환해야 합니다. 여러 행이 나오면 SQL 전체가 에러로 실패합니다.
•
테스트에서 통과해도 운영 데이터에서 여러 행이 생길 수 있습니다. 조건이 1건을 보장하는지(PK) 확인합니다.
•
여러 행이 나올 수 있으면 요건에 따라 SUM 등으로 집계하거나, ORDER BY와 LIMIT 1로 한 건을 고릅니다.
TIP. 에러만 없애는 수정은 위험합니다
•
에러를 없애려고 LIMIT 1만 붙이면 어떤 행이 나올지 알 수 없습니다. 반드시 업무 요건에 맞는 ORDER BY와 함께 씁니다.
•
MAX()로 감싸는 것도 요건이 '최댓값'일 때만 맞습니다.
DEEP DIVE — SQL STARTER for MySQL


