Claire's Study Note

[SQL BOOSTER] 3-2. OUTER JOIN

by Hi.Claire
๋ฐ˜์‘ํ˜•

๐Ÿ“š SQL BOOSTER (์œ ์ผํ™˜, DBian)

 

CH3. JOIN

3-2. OUTER JOIN

3-2-1. OUTER JOIN ์ดํ•ดํ•˜๊ธฐ

Outer Join์€ ์กฐ์ธ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋„ ๊ฒฐ๊ณผ์— ๋‚˜์˜จ๋‹ค.

 

Outer Join์˜ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ

๊ธฐ์ค€ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ : Outer Join์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ์ง‘ํ•ฉ, Outer ์ง‘ํ•ฉ์ด๋ผ๊ณ ๋„ ํ•œ๋‹ค.

์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ : Outer Join์˜ ์ฐธ์กฐ๊ฐ€ ๋˜๋Š” ์ง‘ํ•ฉ, Inner ์ง‘ํ•ฉ์ด๋ผ๊ณ ๋„ ํ•œ๋‹ค.

 

๊ธฐ์ค€ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ(Outer ์ง‘ํ•ฉ)์€ ์กฐ์ธ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ์•Š์•„๋„ ๋ชจ๋‘ ๊ฒฐ๊ณผ์— ํฌํ•จ๋œ๋‹ค.

๋‹จ, ํ•„ํ„ฐ ์กฐ๊ฑด์€ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค.

 

Outer Join์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์ชฝ์˜ ์กฐ์ธ ์กฐ๊ฑด ์ปฌ๋Ÿผ์— (+) ํ‘œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

ANSI๋กœ๋Š” ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์„ LEFT OUTER JOINํ•œ๋‹ค.

 

๊ทธ๋Ÿผ ๋จผ์ € Inner Join๊ณผ Outer Join์„ ๋น„๊ตํ•ด๋ณด์ž.

 

์˜ˆ์‹œ1. ๊ณ ๊ฐ 'CUS_0002'์˜ ๊ณ ๊ฐ(M_CUS) ์ •๋ณด์™€ ์•„์ดํ…œ ํ‰๊ฐ€(T_ITM_EVL) ์ •๋ณด ๊ตฌํ•˜๊ธฐ

 

๊ณ ๊ฐ(M_CUS) ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์€ ๊ณ ๊ฐ 'CUS_0002'์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

SELECT *
FROM m_cus cus
WHERE cus.cus_id = 'CUS_0002';

 

 

์•„์ดํ…œ ํ‰๊ฐ€(T_ITM_EVL) ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์€ ๊ณ ๊ฐ 'CUS_0002'์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค.

SELECT *
FROM t_itm_evl evl
WHERE evl.cus_id = 'CUS_0002';

 

 

์ด๋•Œ ์กฐ์ธ ์กฐ๊ฑด(cus.cus_id = evl.cus_id)์— ๋Œ€ํ•œ Inner Join๊ณผ Outer Join์˜ ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‹ฌ๋ผ์ง€๋Š”์ง€ ์‚ดํŽด๋ณด์ž.

 

(Inner Join, Oracle)

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no
FROM m_cus cus,
     t_itm_evl evl
WHERE cus.cus_id = 'CUS_0002'
AND   cus.cus_id = evl.cus_id;

 

Inner Join์€ ์•„๋ฌด ๊ฒฐ๊ณผ๋„ ์กฐํšŒ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

(Outer Join, Oracle)

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no
FROM m_cus cus,
     t_itm_evl evl
WHERE cus.cus_id = 'CUS_0002'
AND   cus.cus_id = evl.cus_id (+);

 

๋ฐ˜๋ฉด Outer Join์€ 'CUS_0002' ๊ณ ๊ฐ์˜ ์ •๋ณด๊ฐ€ ์กฐํšŒ๋œ๋‹ค.

 

์ด์™€ ๊ฐ™์ด Outer Join์€ ์กฐ์ธ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•œ ๋ฐ์ดํ„ฐ๋„ ๊ฒฐ๊ณผ์— ํฌํ•จ๋˜์–ด ๋‚˜์˜จ๋‹ค.

์ด๋•Œ ๊ธฐ์ค€ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ ์ฐธ์กฐ์ชฝ ๊ฒฐ๊ณผ๋Š” ๊ฐ’์ด NULL๋กœ ์ฑ„์›Œ์ง€๊ฒŒ ๋œ๋‹ค. 

 

์˜ˆ์‹œ1์˜ ANSI ์ฟผ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

(Inner Join, ANSI)

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no
FROM m_cus cus
JOIN t_itm_evl evl
ON cus.cus_id = evl.cus_id
WHERE cus.cus_id = 'CUS_0002';

 

(Outer Join, ANSI)

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no
FROM m_cus cus
LEFT JOIN t_itm_evl evl
ON cus.cus_id = evl.cus_id
WHERE cus.cus_id = 'CUS_0002';

 

์˜ˆ์‹œ2. ๋‘ ๋ช…์˜ ๊ณ ๊ฐ('CUS_0002', 'CUS_0011')์„ ์•„์ดํ…œ ํ‰๊ฐ€(T_ITM_EVL)์™€ Outer Joinํ•˜๊ธฐ

 

(๋‚˜์˜ ํ’€์ด, ANSI)

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl_lst_no
FROM m_cus cus
LEFT JOIN t_itm_evl evl
ON cus.cus_id = evl.cus_id
WHERE cus.cus_id IN ('CUS_0002', 'CUS_0011')
ORDER BY 1;

 

(๊ต์žฌ ํ’€์ด, Oracle)

SELECT  T1.CUS_ID ,T1.CUS_NM ,T2.CUS_ID ,T2.ITM_ID ,T2.EVL_LST_NO
FROM    M_CUS T1
        ,T_ITM_EVL T2
WHERE   T1.CUS_ID IN ('CUS_0002','CUS_0011')
AND     T1.CUS_ID = T2.CUS_ID(+)
ORDER BY T1.CUS_ID;

 

 

์œ„ SQL์ด ์ฒ˜๋ฆฌ๋˜๋Š” ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1. m_cus์—์„œ 'CUS_0002', 'CUS_0011' ๋‘ ๊ฑด์˜ ๊ณ ๊ฐ์ด ํ•„ํ„ฐ๋ง ๋œ๋‹ค.

2. cus.cus_id = evl.cus_id์„ ์กฐ๊ฑด์œผ๋กœ Outer Join์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • m_cus๋Š” ๊ธฐ์ค€ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ(Outer ์ง‘ํ•ฉ)์ด๋‹ค.
  • t_itm_evl์€ ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ(Inner ์ง‘ํ•ฉ)์ด๋‹ค.
  • ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์— 'CUS_0002'๋Š” ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ NULL ๊ฐ’์œผ๋กœ ์ฑ„์›Œ์ง„๋‹ค.

 

3-2-2. OUTER JOIN์˜ ํ•„ํ„ฐ ์กฐ๊ฑด

Outer Join์—์„œ๋Š” ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ ํ•„ํ„ฐ ์กฐ๊ฑด์—๋„ (+) ํ‘œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

 

์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ ํ•„ํ„ฐ ์กฐ๊ฑด์— (+) ์‚ฌ์šฉ ์‹œ Outer Join ์ „์— ํ•„ํ„ฐ ์กฐ๊ฑด์ด ์‚ฌ์šฉ๋œ๋‹ค.

์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ ํ•„ํ„ฐ ์กฐ๊ฑด์— (+) ๋ฏธ์‚ฌ์šฉ ์‹œ Outer Join ํ›„, ์กฐ์ธ ๊ฒฐ๊ณผ์— ํ•„ํ„ฐ ์กฐ๊ฑด์ด ์‚ฌ์šฉ๋œ๋‹ค.

 

์˜ˆ์‹œ1. ํ•„ํ„ฐ ์กฐ๊ฑด์— (+) ํ‘œ์‹œ ์œ ๋ฌด์— ๋”ฐ๋ฅธ ๊ฒฐ๊ณผ ๋น„๊ต

๊ณ ๊ฐ('CUS_0073')์„ ์•„์ดํ…œํ‰๊ฐ€(T_ITM_EVL)์™€ Outer Joinํ•˜๊ธฐ

 

(์ฐธ์กฐ ์ชฝ ํ•„ํ„ฐ ์กฐ๊ฑด์— (+) ํ‘œ์‹œ ์—†์Œ)

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no, evl.evl_dt
FROM m_cus cus
    , t_itm_evl evl
WHERE cus.cus_id IN ('CUS_0073')
AND cus.cus_id = evl.cus_id(+)
AND evl.evl_dt >= to_date('20170201', 'yyyymmdd')
AND evl.evl_dt < to_date('20170301', 'yyyymmdd');

 

 

์œ„ ์ฟผ๋ฆฌ์—์„œ๋Š” Outer Join์˜ ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ ์ชฝ ํ•„ํ„ฐ ์กฐ๊ฑด์— (+) ํ‘œ์‹œ๊ฐ€ ์—†๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ Outer Join์ด ๋จผ์ € ์ฒ˜๋ฆฌ๋œ ํ›„, ๊ทธ ์กฐ์ธ ๊ฒฐ๊ณผ์— ํ•„ํ„ฐ ์กฐ๊ฑด์ด ์ ์šฉ๋œ๋‹ค.

Outer Join์ด ์ด๋ฃจ์–ด์ง€๋ฉด ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ EVL_DT๋Š” NULL์ด ๋œ๋‹ค.

์ด NULL ๊ฐ’์— ๋Œ€ํ•ด 6, 7๋ฒˆ ๋ผ์ธ์˜ ํ•„ํ„ฐ ์กฐ๊ฑด์„ ์ ์šฉํ•˜๋ฉด ์ด๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๊ฒฐ๊ตญ ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค.

์ด๋Š” ๊ฒฐ๊ณผ์ ์œผ๋กœ Inner Join๊ณผ ๊ฐ™๋‹ค.

 

(์ฐธ์กฐ ์ชฝ ํ•„ํ„ฐ ์กฐ๊ฑด์— (+) ํ‘œ์‹œ ์žˆ์Œ)

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no, evl.evl_dt
FROM m_cus cus
    , t_itm_evl evl
WHERE cus.cus_id IN ('CUS_0073')
AND cus.cus_id = evl.cus_id(+)
AND evl.evl_dt(+) >= to_date('20170201', 'yyyymmdd')
AND evl.evl_dt(+) < to_date('20170301', 'yyyymmdd');

 

 

์œ„์™€ ๊ฐ™์ด Outer Join ์‹œ์—๋Š” ์ฐธ์กฐ ์ชฝ ํ•„ํ„ฐ ์กฐ๊ฑด์— (+) ํ‘œ์‹œ๋ฅผ ํ•ด์ค˜์•ผ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐํšŒ๋œ๋‹ค.

 

์œ„์˜ ์˜ˆ์‹œ 1์„ ANSI๋กœ ํ’€์ดํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

(WHERE ์กฐ๊ฑด์— ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ ํ•„ํ„ฐ ์กฐ๊ฑด์„ ์ค€ ๊ฒฝ์šฐ(ANSI))

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no, evl.evl_dt
FROM m_cus cus
LEFT JOIN t_itm_evl evl
ON cus.cus_id = evl.cus_id
WHERE cus.cus_id = 'CUS_0073'
AND evl.evl_dt >= to_date('20170201', 'yyyymmdd')
AND evl.evl_dt < to_date('20170301', 'yyyymmdd');

 

 

(JOIN ์กฐ๊ฑด์— ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ ํ•„ํ„ฐ ์กฐ๊ฑด์„ ์ค€ ๊ฒฝ์šฐ(ANSI))

SELECT cus.cus_id, cus.cus_nm, evl.cus_id, evl.itm_id, evl.evl_lst_no, evl.evl_dt
FROM m_cus cus
LEFT JOIN t_itm_evl evl
ON cus.cus_id = evl.cus_id
AND evl.evl_dt >= to_date('20170201', 'yyyymmdd')
AND evl.evl_dt < to_date('20170301', 'yyyymmdd')
WHERE cus.cus_id = 'CUS_0073';

 

 

ANSI๋กœ Outer Joinํ•  ๋•Œ์—๋Š” ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ ์ชฝ ํ•„ํ„ฐ ์กฐ๊ฑด์„ Join ์กฐ๊ฑด์— ์ฃผ์–ด์•ผ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

 

3-2-3. ์‹คํ–‰์ด ๋ถˆ๊ฐ€๋Šฅํ•œ OUTER JOIN

Oracle์˜ Outer Join์—์„œ ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์€ ๊ธฐ์ค€ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์„ ๋™์‹œ์— ๋‘ ๊ฐœ ์ด์ƒ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค.

 

์˜ˆ์‹œ1. ์‹คํ–‰์ด ๋ถˆ๊ฐ€๋Šฅํ•œ Outer Join

SELECT  T1.CUS_ID ,T2.ITM_ID ,T1.ORD_DT ,T3.ITM_ID ,T3.EVL_PT
FROM    T_ORD T1
        ,T_ORD_DET T2
        ,T_ITM_EVL T3
WHERE   T1.ORD_SEQ = T2.ORD_SEQ
AND     T1.CUS_ID = 'CUS_0002'
AND     T1.ORD_DT >= TO_DATE('20170122','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170123','YYYYMMDD')
AND     T3.CUS_ID(+) = T1.CUS_ID
AND     T3.ITM_ID(+) = T2.ITM_ID;

 

์œ„์˜ 9, 10 ๋ผ์ธ์„ ๋ณด๋ฉด T3(์•„์ดํ…œํ‰๊ฐ€)๋Š” T1(์ฃผ๋ฌธ), T2(์ฃผ๋ฌธ์ƒ์„ธ)์™€ ๋™์‹œ์— Outer Join์„ ํ•˜๊ณ  ์žˆ๋‹ค.

์œ„ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

"ORA-01417: a table may be outer joined to at most one other table Position: 310"

 

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

 

์ฒซ ๋ฒˆ์งธ๋Š” ์ธ๋ผ์ธ-๋ทฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 

์˜ˆ์‹œ2. ์ธ๋ผ์ธ-๋ทฐ๋ฅผ ์‚ฌ์šฉํ•ด ๋ถˆ๊ฐ€๋Šฅํ•œ Outer Join ํ•ด๊ฒฐ

SELECT T1.cus_id, T1.itm_id, T1.ord_dt, T2.itm_id, T2.evl_pt
FROM (SELECT ord.cus_id, det.itm_id, ord.ord_dt
      FROM t_ord ord,
           t_ord_det det
      WHERE ord.ord_seq = det.ord_seq
        AND ord.cus_id = 'CUS_0002'
        AND ord.ord_dt >= to_date('20170122', 'yyyymmdd')
        AND ord.ord_dt < to_date('20170123', 'yyyymmdd')) T1,
     t_itm_evl T2
WHERE T2.cus_id(+) = T1.cus_id
  AND T2.itm_id(+) = T1.itm_id
ORDER BY 1,2;

 

๋‘ ๋ฒˆ์งธ๋Š” ANSI ํ‘œ์ค€ SQL์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 

์˜ˆ์‹œ3. ANSI ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋ถˆ๊ฐ€๋Šฅํ•œ Outer Join ํ•ด๊ฒฐ

SELECT ord.cus_id, det.itm_id, ord.ord_dt, evl.itm_id, evl.evl_pt
FROM t_ord ord
JOIN t_ord_det det
ON ord.ord_seq = det.ord_seq
LEFT JOIN t_itm_evl evl
ON ord.cus_id = evl.cus_id
AND det.itm_id = evl.itm_id
WHERE ord.cus_id = 'CUS_0002'
AND ord.ord_dt >= to_date('20170122', 'yyyymmdd')
AND ord.ord_dt < to_date('20170123', 'yyyymmdd')
ORDER BY 1,2;

 

๋‹จ, Oracle์—์„œ ANSI ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ์œ„ํ•œ ํžŒํŠธ๊ฐ€ ์ž˜ ์•ˆ ๋จน๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฐธ๊ณ ํ•˜์ž.

 

3-2-4. OUTER JOIN์ด ํฌํ•จ๋œ ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์˜ ์กฐ์ธ

ํ•˜๋‚˜์˜ SQL์—์„œ Outer Join๊ณผ Inner Join์„ ๋™์‹œ์— ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•  ์ ์ด ์žˆ๋‹ค.

์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด์ž.

 

์˜ˆ์‹œ1. Outer Join๊ณผ Inner Join์„ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋Š” SQL

SELECT  T1.CUS_ID ,T2.ORD_SEQ ,T2.ORD_DT ,T3.ORD_SEQ ,T3.ITM_ID
FROM    M_CUS T1
        ,T_ORD T2
        ,T_ORD_DET T3
WHERE   T1.CUS_ID = 'CUS_0073'
AND     T1.CUS_ID = T2.CUS_ID(+)
AND     T2.ORD_DT(+) >= TO_DATE('20170122','YYYYMMDD')
AND     T2.ORD_DT(+) < TO_DATE('20170123','YYYYMMDD')
AND     T3.ORD_SEQ = T2.ORD_SEQ;

 

 

์œ„ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค.

๊ทธ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

์ฟผ๋ฆฌ ์ˆ˜ํ–‰ ๊ณผ์ •์„ ์ฐจ๋ก€๋Œ€๋กœ ์‚ดํŽด๋ณด์ž.

๋จผ์ € T1(๊ณ ๊ฐ)๊ณผ T2(์ฃผ๋ฌธ)๊ฐ€ Outer Join์„ ํ•˜๊ณ  ์žˆ๋‹ค.

SELECT  T1.CUS_ID ,T2.ORD_SEQ ,T2.ORD_DT
--      ,T3.ORD_SEQ ,T3.ITM_ID
FROM    M_CUS T1
        ,T_ORD T2
--         ,T_ORD_DET T3
WHERE   T1.CUS_ID = 'CUS_0073'
AND     T1.CUS_ID = T2.CUS_ID(+)
AND     T2.ORD_DT(+) >= TO_DATE('20170122','YYYYMMDD')
AND     T2.ORD_DT(+) < TO_DATE('20170123','YYYYMMDD')
-- AND     T3.ORD_SEQ = T2.ORD_SEQ;

 

 

T2(์ฃผ๋ฌธ) ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์—๋Š” ๊ณ ๊ฐ 'CUS_0073'์˜ ์ •๋ณด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— Outer Join์˜ ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์ชฝ ๊ฒฐ๊ณผ๋Š” NULL์ด ๋œ๋‹ค.

 

๋‹ค์‹œ ์›๋ž˜ ์ฟผ๋ฆฌ๋ฅผ ์‚ดํŽด๋ณด๋ฉด 9๋ฒˆ ๋ผ์ธ์—์„œ T2(์ฃผ๋ฌธ)๊ณผ T3(์ฃผ๋ฌธ์ƒ์„ธ)๊ฐ€ ORD_SEQ ์ปฌ๋Ÿผ์œผ๋กœ Inner Join์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ T1๊ณผ Outer Join ์ˆ˜ํ–‰ ํ›„ T2์˜ ORD_SEQ๋Š” NULL๊ฐ’์„ ๊ฐ€์ง„๋‹ค.

NULL๊ฐ’์€ ๋น„๊ต๋ฅผ ํ•  ์ˆ˜ ์—†๋‹ค.

๋”ฐ๋ผ์„œ ๊ฒฐ๊ณผ์ ์œผ๋กœ ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๊ฒŒ ๋œ๋‹ค.

 

์กฐ์ธ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๊ฒŒ ํ•˜๋ ค๋ฉด T3๋„ T2์— Outer Join์„ ๊ฑธ์–ด์ค˜์•ผ ํ•œ๋‹ค.

SELECT  T1.CUS_ID ,T2.ORD_SEQ ,T2.ORD_DT ,T3.ORD_SEQ ,T3.ITM_ID
FROM    M_CUS T1
        ,T_ORD T2
        ,T_ORD_DET T3
WHERE   T1.CUS_ID = 'CUS_0073'
AND     T1.CUS_ID = T2.CUS_ID(+)
AND     T2.ORD_DT(+) >= TO_DATE('20170122','YYYYMMDD')
AND     T2.ORD_DT(+) < TO_DATE('20170123','YYYYMMDD')
AND     T3.ORD_SEQ(+) = T2.ORD_SEQ;

 

 

(ANSI ํ’€์ด)

SELECT cus.cus_id, ord.ord_seq, ord.ord_dt, det.ord_seq, det.itm_id
FROM m_cus cus
LEFT JOIN t_ord ord
ON cus.cus_id = ord.cus_id
AND ord.ord_dt >= to_date('20170122', 'yyyymmdd')
AND ord.ord_dt < to_date('20170123', 'yyyymmdd')
LEFT JOIN t_ord_det det
ON ord.ord_seq = det.ord_seq
WHERE cus.cus_id = 'CUS_0073';

 

์œ„ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•˜๋ฉด, ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์ด ์กฐ์ธ๋  ๋•Œ Outer Join์ด ์ˆ˜ํ–‰๋œ ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์€ ๊ธฐ์ค€ ์ง‘ํ•ฉ์ด ๋˜์–ด์„œ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”๊ณผ Outer Joinํ•ด์•ผ ํ•œ๋‹ค.

 

3-2-5. OUTER JOIN์˜ ์‘์šฉ

Outer Join์€ ์กฐ์ธ์— ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•ด๋„ ๊ธฐ์ค€ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์€ ๋ฌด์กฐ๊ฑด ์กฐํšŒ๋˜๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ํŠน์ง•์€ ๋ถ„์„ ๋ฆฌํฌํŠธ์—์„œ ์‹ค์ ์ด ์—†๋Š” ๋งˆ์Šคํ„ฐ๋„ ๊ฒฐ๊ณผ์— ํฌํ•จ์‹œํ‚ฌ ๋•Œ ์œ ์šฉํ•˜๋‹ค.

 

์˜ˆ์‹œ1. ๊ณ ๊ฐ๋ณ„ 1์›”์˜ ์ฃผ๋ฌธ ๊ฑด์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” SQL (์ฃผ๋ฌธ์ด ์—†๋Š” ๊ณ ๊ฐ์€ ์ฃผ๋ฌธ ๊ฑด์ˆ˜๊ฐ€ 0์œผ๋กœ ์กฐํšŒ๋˜์–ด์•ผ ํ•œ๋‹ค.)

SELECT cus.cus_id, count(*) AS cnt, count(ord.ord_seq) AS ord_cnt
FROM m_cus cus
LEFT JOIN t_ord ord
ON cus.cus_id = ord.cus_id
AND ord.ord_dt >= to_date('20170101', 'yyyymmdd')
AND ord.ord_dt < to_date('20170201', 'yyyymmdd')
GROUP BY cus.cus_id
ORDER BY 1;

 

 

์ฃผ๋ฌธ ๊ฑด์ˆ˜๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด COUNT() ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ๋‘ ๋ฒˆ์งธ ์ปฌ๋Ÿผ์€ COUNT(*)์„ ์ˆ˜ํ–‰ํ–ˆ๊ณ , ์„ธ ๋ฒˆ์งธ ์ปฌ๋Ÿผ์€ COUNT(ord.ord_seq)๋ฅผ ์ˆ˜ํ–‰ํ–ˆ๋‹ค.

๊ณ ๊ฐ 'CUS_0001'์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, COUNT(*)์˜ ๊ฒฐ๊ณผ๋Š” 1๊ฑด์ด๊ณ , COUNT(ord.ord_seq)์˜ ๊ฒฐ๊ณผ๋Š” 0๊ฑด์ด๋‹ค.

์ด ์ค‘์— ํ•„์š”ํ•œ ๊ฒฐ๊ณผ๋Š” COUNT(ord.ord_seq)์„ ์‚ฌ์šฉํ•œ ๊ฒฐ๊ณผ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ๊ณ ๊ฐ 'CUS_0001'์€ 1์›”์— ์ฃผ๋ฌธ์ด ํ•˜๋‚˜๋„ ์—†๋Š” ๊ณ ๊ฐ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ด์ฒ˜๋Ÿผ Outer Join๊ณผ COUNT() ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ํ•ญ์ƒ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

COUNT() ๋Œ€์ƒ์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

COUNT() ๋Œ€์ƒ์ด ์‹ค์ ์˜ ๊ฑด์ˆ˜๋ผ๋ฉด ์œ„์˜ COUNT(ord.ord_seq)์™€ ๊ฐ™์ด ์ฐธ์กฐ ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

COUNT() ๋Œ€์ƒ์ด NULL๊ฐ’์„ ํฌํ•จํ•œ ์กฐ์ธ ๊ฒฐ๊ณผ ์ž์ฒด์˜ ๊ฑด์ˆ˜๋ผ๋ฉด COUNT(*)์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

์˜ˆ์‹œ2. 'PC, ELEC' ์•„์ดํ…œ ์œ ํ˜•์˜ ์•„์ดํ…œ๋ณ„ 1์›”์˜ ์ฃผ๋ฌธ ์ˆ˜๋Ÿ‰ ๊ตฌํ•˜๊ธฐ (์ฃผ๋ฌธ์ด ์—†์–ด๋„ 0์œผ๋กœ ๋‚˜์™€์•ผ ํ•œ๋‹ค.)

SELECT T1.ITM_ID, T1.ITM_NM, NVL(T2.ORD_QTY,0) AS ORD_QTY
FROM M_ITM T1
    , (SELECT B.ITM_ID, SUM(ORD_QTY) AS ORD_QTY
       FROM T_ORD A,
            T_ORD_DET B
       WHERE A.ORD_SEQ = B.ORD_SEQ
       AND A.ORD_ST = 'COMP' -- ์ฃผ๋ฌธ์ƒํƒœ=์™„๋ฃŒ
       AND A.ORD_DT >= TO_DATE('20170101', 'yyyymmdd')
       AND A.ORD_DT < TO_DATE('20170201', 'yyyymmdd')
       GROUP BY B.ITM_ID) T2
WHERE T1.ITM_ID = T2.ITM_ID(+)
AND T1.ITM_TP IN ('PC', 'ELEC')
ORDER BY 1;

 

 

์ธ๋ผ์ธ-๋ทฐ๋ฅผ ์‚ฌ์šฉํ•ด ์‹ค์  ๋ฐ์ดํ„ฐ๋ฅผ M_ITM ํ…Œ์ด๋ธ”์˜ PK ๋‹จ์œ„์ธ ITM_ID๋กœ Group Byํ•œ ํ›„์— ์กฐ์ธํ•˜๊ณ  ์žˆ๋‹ค.

์ด์™€ ๊ฐ™์ด SQL์„ ์ž‘์„ฑํ•˜๋ฉด ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง€๊ณ , ๊ฒฐ๊ณผ์ ์œผ๋กœ ์œ ์ง€ ๋ณด์ˆ˜์—๋„ ๋„์›€์ด ๋œ๋‹ค.

๋ฐ˜์‘ํ˜•

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Claire's Study Note

Hi.Claire

ํ™œ๋™ํ•˜๊ธฐ