두 테이블의 관계 차수를 파악하고, 두 테이블을 조인하는 것은 크게 어렵지 않다. 그리고 두 테이블은 1:M 관계로 이루어진 경우가 대부분이다. 결국, 두 테이블 간에 조인은 1:M 관계일 가능성이 높다. 이제는 난이도를 조금 높여서 세 테이블의 관계 차수를 살펴보고 그에 맞게 조인을 작성해보자.
아래는 매장, 주문, 회원 테이블이다. 매장과 주문은 1:M, 주문과 회원이 M:1이다. 그러므로 세 테이블은 주문을 중심으로 1:M:1 관계가 된다.


1:M:1과 같은 관계에서는 테이블 간에 조인 컬럼만 잘 고려해서 SQL을 작성하면 된다. 아래는 2018년 3월 27일에 오픈한 매장에 대해, 플래티넘 회원의 2020년 1월 주문을 조회하는 SQL이다.
-- [SQL-9-3-1-a] 1:M:1 조인
SELECT T2.OrdNo ,T2.OrdDtm ,T2.OrdAmt
,T1.ShopId ,T1.ShopNm
,T3.MemberId ,T3.NickNm
FROM startdb.Shop T1
INNER JOIN startdb.Ord T2
ON (T2.ShopId = T1.ShopId)
INNER JOIN startdb.Member T3
ON (T3.MemberId = T2.MemberId)
WHERE T1.ShopStartYmd = '20180327'
AND T2.OrdDtm >= STR_TO_DATE('20200101','%Y%m%d')
AND T2.OrdDtm < STR_TO_DATE('20200201','%Y%m%d')
AND T3.MemberGd = 'PLAT';
OrdNo OrdDtm OrdAmt ShopId ShopNm MemberId NickNm
----- ------------------- -------- ------ ------------- -------- ---------
1232 2020-01-02 13:00:00 8000.000 S028 San Diego-2nd M0298 Thunder5
1244 2020-01-05 10:00:00 8500.000 S014 Columbus-1st M0291 Star5
1285 2020-01-11 10:00:00 7500.000 S014 Columbus-1st M0291 Star5
1298 2020-01-11 11:00:00 4000.000 S014 Columbus-1st M1283 Quantum25
1315 2020-01-11 12:00:00 7500.000 S031 Austin-2nd M1297 Swift25
1352 2020-01-23 10:00:00 8500.000 S014 Columbus-1st M0291 Star5
1367 2020-01-23 11:00:00 4000.000 S014 Columbus-1st M1283 Quantum25
1387 2020-01-23 12:00:00 4000.000 S031 Austin-2nd M1297 Swift25
1414 2020-01-29 10:00:00 4000.000 S014 Columbus-1st M0291 Star5
1429 2020-01-29 11:00:00 4000.000 S014 Columbus-1st M1283 Quantum25
1449 2020-01-29 12:00:00 4000.000 S031 Austin-2nd M1297 Swift25
1486 2020-01-30 13:00:00 2500.000 S028 San Diego-2nd M0298 Thunder5
위 SQL은 아래 그림과 같이, Shop은 Ord만큼 데이터가 늘어나고, Member는 Shop과 Ord의 조인 결과만큼 데이터가 늘어난게 된다. 1:M:1 조인에서 1쪽은 M만큼 데이터가 늘어날 수 있다.

위 SQL을 조금더 발전시켜, MemberId별로 주문금액 합계를 구해보자. 다음과 같이 SQL을 변경하면 된다.
-- [SQL-9-3-1-b] 1:M:1 조인후 GROUP BY
SELECT T3.MemberId ,MAX(T3.NickNm) NickNm
,SUM(T2.OrdAmt) SumOrdAmt
FROM startdb.Shop T1
INNER JOIN startdb.Ord T2
ON (T2.ShopId = T1.ShopId)
INNER JOIN startdb.Member T3
ON (T3.MemberId = T2.MemberId)
WHERE T1.ShopStartYmd = '20180327'
AND T2.OrdDtm >= STR_TO_DATE('20200101','%Y%m%d')
AND T2.OrdDtm < STR_TO_DATE('20200201','%Y%m%d')
AND T3.MemberGd = 'PLAT'
GROUP BY T3.MemberId
ORDER BY T3.MemberId;
MemberId NickNm SumOrdAmt
-------- --------- ----------
M0291 Star5 28500.000
M0298 Thunder5 10500.000
M1283 Quantum25 12000.000
M1297 Swift25 15500.000
1:M:1 관계를 모두 조인 후 GROUP BY 처리했다. 데이터 집합이 처리되는 과정을 개념적으로 그려보면 다음과 같다. 1인 데이터 집합은 M쪽 만큼 데이터가 늘어난 후, GROUP BY 컬럼의 값 종류만큼 줄어들게 된다.