앞에서는 1:M:1 관계의 조인을 살펴봤다. 1:M:1은 인라인 뷰를 활용해도 되고 인라인 뷰를 활용하지 않아도 된다. 이제 소개할 M:1:M 관계는 가능하면 인라인 뷰를 활용해 처리해야 한다.
다양한 사이트에서 개발된 SQL들을 보면 M:1:M 관계를 인라인 뷰 없이 직접 조인 처리하는 실수를 많이 목격하게 된다. M:1:M 관계의 세 테이블은 일반적으로 직접 조인할 수 없다. 적절한 인라인 뷰와 GROUP BY 처리가 필요하다.
아래는 1(회원)을 중심으로 두 개의 M 테이블(주문, 이벤트응모)이 있는 M:1:M 관계다. 시스템의 업무가 많고 복잡할 수록 이와 같은 M:1:M 관계가 자주 만들어진다. 테이블 구조와 관계 자체는 정상적이다. 다만, 이러한 관계의 세 개 테이블을 조인할 때는 주의가 필요하다.

M0253 회원에 대해 회원 정보와 주문 정보, 이벤트응모(EventEntry) 정보를 각각 조회해보자.
-- [SQL-9-4-1-a]
-- 회원 정보
SELECT T1.MemberId ,T1.NickNm
FROM startdb.Member T1
WHERE T1.MemberId = 'M0253';
MemberId NickNm
-------- ------
M0253 Cloud5
-- [SQL-9-4-1-b]
-- 주문 정보(2019.10~2019.12), 주문금액이 8,000 이상만
SELECT T2.MemberId ,T2.OrdNo ,T2.OrdDtm ,T2.OrdAmt
FROM startdb.Ord T2
WHERE T2.MemberId = 'M0253'
AND T2.OrdDtm >= STR_TO_DATE('20191101','%Y%m%d')
AND T2.OrdDtm < STR_TO_DATE('20200101','%Y%m%d')
AND T2.OrdAmt >= 8000
ORDER BY T2.OrdNo;
MemberId OrdNo OrdDtm OrdAmt
-------- ----- ------------------- ---------
M0253 284 2019-11-11 11:00:00 8500.000
M0253 730 2019-12-23 11:00:00 10000.000
M0253 970 2019-12-25 11:00:00 12500.000
-- [SQL-9-4-1-c]
-- 이벤트응모 정보(2019.10~2019.12)
SELECT T3.MemberId ,T3.EventId, T3.EntryDtm
FROM startdb.EventEntry T3
WHERE T3.MemberId = 'M0253'
AND T3.EntryDtm >= STR_TO_DATE('20191101','%Y%m%d')
AND T3.EntryDtm < STR_TO_DATE('20200101','%Y%m%d')
ORDER BY T3.EventId;
MemberId EventId EntryDtm
-------- ------- -------------------
M0253 EV0007 2019-11-07 08:07:13
M0253 EV0008 2019-12-15 06:07:13
위 세 테이블의 데이터를 조인해 아래와 같이 회원의 2019년 11월~12월 주문 건수(8,000원 이상의 주문)와 같은 기간의 이벤트 응모 횟수를 보여주려고 한다.
MemberId NickNm OrdCnt EntryCnt
-------- ------ ------ --------
M0253 Cloud5 3 2
