๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
SQL/SQL ๋ ˆ๋ฒจ์—…

[SQL ๋ ˆ๋ฒจ์—…] 5์žฅ: ๋ฐ˜๋ณต๋ฌธ

by oliviarla 2022. 4. 18.

๋ฐ˜๋ณต๋ฌธ ์˜์กด

1. ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉ

๋ฐ˜๋ณต๋ฌธ์— ์ต์ˆ™ํ•œ ๊ฐœ๋ฐœ์ž๋“ค์€ ๋‹ค์Œ์˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด ๋ ˆ์ฝ”๋“œ์— ํ•˜๋‚˜์”ฉ ์ ‘๊ทผํ•˜๊ณ  ํ˜ธ์ŠคํŠธ ์–ธ์–ด(์ ˆ์ฐจํ˜• ์–ธ์–ด)์—์„œ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๊ฐ„ํ˜น ์žˆ์Œ

  • ์˜จ๋ผ์ธ ์ฒ˜๋ฆฌ์—์„œ ํ™”๋ฉด์— ๋ช…์„ธ๋ฅผ ์ถœ๋ ฅํ•˜์กฐ๊ฐ€ ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜์”ฉ ์ ‘๊ทผํ•˜๋Š” SELECT ๊ตฌ๋ฌธ ๋ฐ˜๋ณต ์‚ฌ์šฉ
  • ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ์—์„œ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ํ˜ธ์ŠคํŠธ ์–ธ์–ด์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  ํ…Œ์ด๋ธ”์— ๊ฐฑ์‹ 

๋ฐ˜๋ณต๊ณ„์˜ ๊ณตํฌ

1. ๋ฐ˜๋ณต๋ฌธ์— ์˜์กดํ•œ ์ฝ”๋“œ์˜ ๋‹จ์ 

- Sales: ๋งค์ถœ ๊ณ„์‚ฐํ•˜๋Š” ํ…Œ์ด๋ธ”

- Sales2: ๋งค์ถœ ๋ณ€ํ™”๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” var ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ ํ…Œ์ด๋ธ”

 

- ์ฒ˜๋ฆฌ ์‹œ๊ฐ„ ๋น„๊ต

๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: (์ฒ˜๋ฆฌ ํšŸ์ˆ˜) * (ํ•œ ํšŒ์— ๊ฑธ๋ฆฌ๋Š” ์ฒ˜๋ฆฌ ์‹œ๊ฐ„)

๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„: SQL ํŒจํ„ด์€ ๋‹ค์–‘ํ•˜์ง€๋งŒ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹คํ–‰ ๊ณ„ํš์˜ ๋ณ€๋™์ด ์—†๋‹ค๋ฉด ๋Œ€๋ถ€๋ถ„ ์™„๋งŒํ•œ ์ปค๋ธŒํ˜•์œผ๋กœ ์ฆ๊ฐ€ํ•  ๊ฒƒ

 

SQL ์‹คํ–‰์˜ ์˜ค๋ฒ„ํ—ค๋“œ

์ „์ฒ˜๋ฆฌ

1. SQL ๊ตฌ๋ฌธ์„ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†ก

2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ

3. SQL ๊ตฌ๋ฌธ Parse

4 .SQL ๊ตฌ๋ฌธ์˜ ์‹คํ–‰ ๊ณ„ํš ์ƒ์„ฑ ๋˜๋Š” ํ‰๊ฐ€

 

ํ›„์ฒ˜๋ฆฌ

5. ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†ก

 

1, 5๋ฒˆ์˜ ๊ฒฝ์šฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ™์€ ๋ฐ์ดํ„ฐ์„ผํ„ฐ ๋‚ด๋ถ€์˜ ๋™์ผ LAN ์œ„์— ์žˆ์œผ๋ฏ€๋กœ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ํฌ๊ฒŒ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ

2๋ฒˆ์˜ ๊ฒฝ์šฐ ์ปค๋„ฅ์…˜ ํ’€์„ ์‚ฌ์šฉํ•ด ๋ฏธ๋ฆฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์—ฐ๊ฒฐ์„ ์ผ์ • ์ˆ˜ ํ™•๋ณดํ•ด ์˜ค๋ฒ„ํ—ค๋“œ ํฌ์ง€ ์•Š์Œ

3๋ฒˆ์˜ ๊ฒฝ์šฐ SQL Parse(๊ตฌ๋ฌธ๋ถ„์„) ํ•  ๋•Œ DBMS๋งˆ๋‹ค ๋ฐฉ๋ฒ•๊ณผ ์ข…๋ฅ˜๊ฐ€ ๋‹ฌ๋ผ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ํผ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ SQL๋ฌธ์„ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜์–ด ์ž‘์€ SQL ๋ฌธ์„ ์—ฌ๋Ÿฌ๋ฒˆ ๋ฐ˜๋ณตํ•  ๊ฒฝ์šฐ ์˜ค๋ฒ„ํ—ค๋“œ ์ปค์ง

๋ณ‘๋ ฌ ๋ถ„์‚ฐ์ด ํž˜๋“ค๋‹ค

๋ฐ˜๋ณต 1ํšŒ๋งˆ๋‹ค ์ฒ˜๋ฆฌ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜์—ฌ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋กœ ์ตœ์ ํ™” ๋ถˆ๊ฐ€๋Šฅ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์„œ๋ฒ„ ์ €์žฅ์†Œ๋Š” ๋Œ€๋ถ€๋ถ„ I/O ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด์žˆ์œผ๋‚˜ ๋ฐ˜๋ณต๋ฌธ์—์„œ ์‹คํ–‰๋˜๋Š” SQL ๊ตฌ๋ฌธ์€ ๋‹จ์ˆœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํšŒ๋‹น ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ ์–‘์ด ์ ์–ด ๋ณ‘๋ ฌํ™” ํ•˜๊ธฐ ํž˜๋“ฆ

์ฆ‰, ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ ํšจ์œจ์ด ์•ˆ์ข‹์Œ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ง„ํ™”๋กœ ์ธํ•œ ํ˜œํƒ ๋ชป๋ฐ›์Œ

๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ณต์žกํ•œ SQL ๊ตฌ๋ฌธ์„ ๋น ๋ฅด๊ฒŒ ํ•˜๋„๋ก ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๊ฐœ์„ ๋˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋‹จ์ˆœ ์ฒ˜๋ฆฌ์˜ ๋ฐ˜๋ณต์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์žฅ์ ์„ ํ™œ์šฉํ•  ์ˆ˜ ์—†์Œ

 

๋ฐ˜๋ณต๋ฌธ ๋Œ€์‹  ๋ณต์žกํ•œ SQL๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ํŠœ๋‹ํ•œ๋‹ค๋ฉด ๋ฐ˜๋ณต๋ฌธ+๋‹จ์ˆœ SQL๋ฌธ ์กฐํ•ฉ๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๊ฐœ์„ ๋  ์ˆ˜ ์žˆ๋‹ค.

2. ๋ฐ˜๋ณต๊ณ„๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

๋ฐ˜๋ณต๋ฌธ+๋‹จ์ˆœ SQL๋ฌธ -> ๋ณต์žกํ•œ SQL๋ฌธ

์‹ค์ œ ์ƒํ™ฉ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ

๊ฐ SQL๋ฌธ์„ ๋น ๋ฅด๊ฒŒ ์ˆ˜์ •

๋Œ€๋ถ€๋ถ„ unique scan, index range scan์ •๋„์˜ ๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ์ด๋‚˜ INSERT ๊ตฌ๋ฌธ์ด๋ฏ€๋กœ ์ˆ˜์ •ํ•œ๋‹ค๊ณ  ํ•ด๋„ ํŠœ๋‹, ๊ณ ์†ํ™” ๊ฐ€๋Šฅ์„ฑ์ด ์ œํ•œ๋จ

๋‹ค์ค‘ํ™” ์ฒ˜๋ฆฌ

๊ฐ€์žฅ ํฌ๋ง์ ์ธ ์„ ํƒ์ง€

์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์ค‘๋„๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•˜์˜€๋‹ค๋ฉด ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†์ด ํ™•์žฅ ๊ฐ€๋Šฅ

์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๊ฑฐ๋‚˜ ๋ณ‘๋ ฌํ™”ํ–ˆ์„ ๋•Œ ๋ฌผ๋ฆฌ์  ์ž์›์ด ๋ถ€์กฑํ•˜๋ฉด ์‚ฌ์šฉ ๋ถˆ๊ฐ€

 

 

์ˆ˜๋ฐฑ~์ˆ˜์ฒœ๋งŒ๋ฒˆ์˜ ๋ฐ˜๋ณต์ด ๊ธฐ๋ณธ์ธ ์ผ๊ด„ ์ฒ˜๋ฆฌ์—์„œ๋Š” ๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉ์„ ์ง€์–‘ํ•˜์ž

3. ๋ฐ˜๋ณต๊ณ„์˜ ์žฅ์ 

์‹คํ–‰ ๊ณ„ํš์˜ ์•ˆ์ •์„ฑ

์‹คํ–‰ ๊ณ„ํš์ด ๋‹จ์ˆœํ•˜์—ฌ ๋ณ€๋™ ์œ„ํ—˜์ด ์—†์Œ

SQL ๊ตฌ๋ฌธ ๋‚ด๋ถ€์—์„œ ๊ฒฐํ•ฉ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋จ -> ๊ฒฐํ•ฉ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ณ€๊ฒฝ์ด ์—†์–ด ์‹คํ–‰ ๊ณ„ํš ๋ณ€๋™ ์ ์Œ

์˜ˆ์ƒ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์˜ ์ •๋ฐ€๋„

์‹คํ–‰ ๊ณ„ํš์ด ๋‹จ์ˆœํ•˜๊ณ  ์„ฑ๋Šฅ์ด ์•ˆ์ •์ ์ด๋ฏ€๋กœ ์˜ˆ์ƒ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์˜ ์ •๋ฐ€๋„๊ฐ€ ๋†’์•„์ง

๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์‹คํ–‰ ๊ณ„ํš์— ๋”ฐ๋ผ ์„ฑ๋Šฅ์ด ์ฒœ์ฐจ๋งŒ๋ณ„์ด๋ฏ€๋กœ ์˜ˆ์ƒํ•˜๊ธฐ ์–ด๋ ค์›€

ํŠธ๋žœ์žญ์…˜ ์ œ์–ด๊ฐ€ ํŽธ๋ฆฌ

ํŠธ๋žœ์žญ์…˜์˜ ์ •๋ฐ€๋„ ์ œ์–ด ๊ฐ€๋Šฅ

๊ฐฑ์‹  ์ฒ˜๋ฆฌ๋‚˜ ํŠน์ • ์ด์œ ๋กœ ๋ฐฐ์น˜๋ฅผ ์ž ์‹œ ์ค‘๋‹จํ•ด์•ผ ํ•  ๋•Œ ํ•ด๋‹น ์ง€์  ๊ทผ์ฒ˜์—์„œ ๋‹ค์‹œ ์ฒ˜๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Œ

SQL์—์„œ ๋ฐ˜๋ณต ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•

1. CASE ์‹๊ณผ ์œˆ๋„์šฐ ํ•จ์ˆ˜

INSERT INTO Sales2
SELECT company, year, sale,
       CASE SIGN(sale-MAX(sale) OVER (PARTITION BY company
                                      ORDER BY year
                                      ROWS BETWEEN 1 PRECEDING
                                               AND 1 PRECEDING) )
       WHEN 0 THEN '='
       WHEN 1 THEN '+'
       WHEN -1 THEN '-'
       ELSE NULL END AS var
FROM Sales;
SIGN ํ•จ์ˆ˜: ์ˆซ์ž ์ž๋ฃŒํ˜•์ด ์Œ์ˆ˜์ด๋ฉด -1, ์–‘์ˆ˜์ด๋ฉด 1, 0์ด๋ฉด 0 ๋ฐ˜ํ™˜
ROWS BETWEEN (๊ฐœ์ˆ˜) PRECEDING AND (๊ฐœ์ˆ˜) PRECEDING: ํ˜„์žฌ ๋ ˆ์ฝ”๋“œ์—์„œ 1๊ฐœ ์ด์ „๋ถ€ํ„ฐ 1๊ฐœ์ด์ „๊นŒ์ง€์˜ ๋ ˆ์ฝ”๋“œ ๋ฒ”์œ„

ํ˜„์žฌ ๋ ˆ์ฝ”๋“œ์˜ sale - 1๊ฐœ ์ด์ „์˜ sale(max ํ•จ์ˆ˜ ์ฒ˜๋ฆฌ๋กœ  ๊ฐ™์€ ํšŒ์‚ฌ์˜ ์ง์ „ ๋งค์ƒ์„ ๊ฐ€์ ธ์˜ด)

 

์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ: ์„œ๋ธŒ์ฟผ๋ฆฌ ๋‚ด๋ถ€์—์„œ ์™ธ๋ถ€ ์ฟผ๋ฆฌ์™€์˜ ๊ฒฐํ•ฉ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•˜๊ณ , ํ•ด๋‹น ๊ฒฐํ•ฉ ํ‚ค๋กœ ์ž˜๋ผ์ง„ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์„ ์กฐ์ž‘ํ•˜๋Š” ๊ธฐ์ˆ 
์ง์ „, ์งํ›„๋ฅผ ๊ตฌํ•  ๋•Œ MAX ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์‹คํ–‰ ๊ณ„ํš ๋ณต์žกํ•ด ์„ฑ๋Šฅ์  ๋ฆฌ์Šคํฌ ๋ฐœ์ƒ, 2~3๋ฒˆ์งธ ์ „ํ›„๋ฅผ ๊ตฌํ•˜๊ธฐ๋„ ์–ด๋ ค์›€
SELECT company, year, sale,
       (SELECT company FROM Sales S2
              WHERE S1.company=S2.company
              AND year=(SELECT MAX(year)
                        FROM Sales S3
                        WHERE S1.company=S3.company
                        AND S1.year>S3.year)) AS pre_company,
       (SELECT sale FROM Sales S2
              WHERE S1.company=S2.company
              AND year=(SELECT MAX(year)
                        FROM Sales S3
                        WHERE S1.company=S3.company
                        AND S1.year>S3.year)) AS pre_sale
FROM Sales S1;

2. ์ตœ๋Œ€ ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ ์ •ํ•ด์ง„ ๊ฒฝ์šฐ

์šฐํŽธ๋ฒˆํ˜ธ '4130033'๊ณผ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ์ฐพ์•„ ์ถœ๋ ฅํ•˜๋Š” ๋ฌธ์ œ

 

์ˆœ์œ„ ๋ถ™์ด๊ธฐ ๋ฌธ์ œ๋กœ ํ’€๊ธฐ

SELECT pcode, district_name
FROM PostalCode
WHERE CASE WHEN pcode='4130033' THEN 0
        WHEN pcode LIKE '413003%' THEN 1
        WHEN pcode LIKE '41300%' THEN 2
        WHEN pcode LIKE '4130%' THEN 3
        WHEN pcode LIKE '413%' THEN 4
        WHEN pcode LIKE '41%' THEN 5
        WHEN pcode LIKE '4%' THEN 6
        ELSE NULL END = 
             (SELECT MIN(CASE WHEN pcode='4130033' THEN 0
                              WHEN pcode LIKE '413003%' THEN 1
                              WHEN pcode LIKE '41300%' THEN 2
                              WHEN pcode LIKE '4130%' THEN 3
                              WHEN pcode LIKE '413%' THEN 4
                              WHEN pcode LIKE '41%' THEN 5
                              WHEN pcode LIKE '4%' THEN 6
                              ELSE NULL END)
              FROM PostalCode);

์ˆœ์œ„๊ฐ€ ๊ฐ€์žฅ ๋†’์€(RANK๊ฐ’์ด ์ž‘์€) ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ์„ ํƒ

์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ์Šค์บ” ํšŸ์ˆ˜ ๊ฐ์†Œ

์ˆœ์œ„์˜ ์ตœ์†Ÿ๊ฐ’์„ ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ ์ฐพ๋Š” ๊ธฐ์กด ๋ฐฉ์‹ -> ์œˆ๋„์šฐ ํ•จ์ˆ˜ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ…Œ์ด๋ธ” ์Šค์บ” ํšŸ์ˆ˜ ์ค„์ž„

SELECT pcode, district_name,
FROM (SELECT pcode, district_name, 
             CASE WHEN pcode='4130033' THEN 0
                  WHEN pcode LIKE '413003%' THEN 1
                  WHEN pcode LIKE '41300%' THEN 2
                  WHEN pcode LIKE '4130%' THEN 3
                  WHEN pcode LIKE '413%' THEN 4
                  WHEN pcode LIKE '41%' THEN 5
                  WHEN pcode LIKE '4%' THEN 6
                  ELSE NULL END AS hit_code,
             MIN(CASE WHEN pcode='4130033' THEN 0
                      WHEN pcode LIKE '413003%' THEN 1
                      WHEN pcode LIKE '41300%' THEN 2
                      WHEN pcode LIKE '4130%' THEN 3
                      WHEN pcode LIKE '413%' THEN 4
                      WHEN pcode LIKE '41%' THEN 5
                      WHEN pcode LIKE '4%' THEN 6
                      ELSE NULL END)
              OVER(ORDER BY CASE WHEN pcode='4130033' THEN 0
                  WHEN pcode LIKE '413003%' THEN 1
                  WHEN pcode LIKE '41300%' THEN 2
                  WHEN pcode LIKE '4130%' THEN 3
                  WHEN pcode LIKE '413%' THEN 4
                  WHEN pcode LIKE '41%' THEN 5
                  WHEN pcode LIKE '4%' THEN 6
                  ELSE NULL END) AS min_code
              FROM PostalCode) Foo
WHERE hit_code=min_Code;

์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ •๋ ฌํ•˜๋Š” ๋น„์šฉ์ด ์ถ”๊ฐ€๋˜์—ˆ์œผ๋‚˜ ํ…Œ์ด๋ธ” ํฌ๊ธฐ๊ฐ€ ํด ๊ฒฝ์šฐ ํ…Œ์ด๋ธ” ํ’€ ์Šค์บ”์„ ์ค„์ด๋Š” ํšจ๊ณผ๊ฐ€ ๋” ํผ

3. ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ ์ •ํ•ด์ง€์ง€ ์•Š์€ ๊ฒฝ์šฐ

์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ชจ๋ธ๊ณผ ์žฌ๊ท€ ์ฟผ๋ฆฌ

ํฌ์ธํ„ฐ ์ฒด์ธ: ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ํ‚ค๋กœ ์‚ผ์•„ ๋ฐ์ดํ„ฐ๋ฅผ ์ค„์ค„์ด ์—ฐ๊ฒฐํ•œ ๊ฒƒ

์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ชจ๋ธ: ํฌ์ธํ„ฐ ์ฒด์ธ์„ ์‚ฌ์šฉํ•œ ํ…Œ์ด๋ธ” ํ˜•์‹

 

์žฌ๊ท€ ๊ณตํ†ต ํ…Œ์ด๋ธ” ์‹(recursion common table expression)์œผ๋กœ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Œ

 

- PostgreSQL ์ฟผ๋ฆฌ

WITH RECURSIVE Explosion (name, pcode, new_pcode, depth)
AS (SELECT name, pcode, new_pcode, 1
    FROM PostalHistory
    WHERE name='A'
          AND new_pcode IS NULL
    UNION
    SELECT Child.name, Child.pcode, Child.new_pcode, depth+1
    FROM Explosion AS Parent, PostalHistory AS Child
    WHERE Parent.pcode=Child.new_pcode
    AND Parent.name=Child.name)
SELECT name, pcode, new_pcode
FROM Explosion
WHERE depth = (SELECT MAX(depth) FROM Explosion);

์žฌ๊ท€ ๊ณตํ†ต ํ…Œ์ด๋ธ” ์‹ Explosion์ด ํฌ์ธํ„ฐ ์ฒด์ธ์„ ํƒ€๊ณ  ์˜ฌ๋ผ๊ฐ€ ๊ณผ๊ฑฐ์˜ ์ฃผ์†Œ๋ฅผ ์ฐพ์Œ

์žฌ๊ท€ ์ˆ˜์ค€์ด ๊ฐ€์žฅ ๊นŠ์€ ๋ ˆ์ฝ”๋“œ -> depth ๊ฐ’์ด ๊ฐ€์žฅ ํฐ ๋ ˆ์ฝ”๋“œ

 

์ค‘์ฒฉ ์ง‘ํ•ฉ ๋ชจ๋ธ

1) ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ชจ๋ธ

๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ•

2) ์ค‘์ฒฉ ์ง‘ํ•ฉ ๋ชจ๋ธ

๊ฐ ๋ ˆ์ฝ”๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘ํ•ฉ์œผ๋กœ ๋ณด๊ณ  ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์ง‘ํ•ฉ์˜ ์ค‘์ฒฉ ๊ด€๊ณ„๋กœ ๋‚˜ํƒ€๋ƒ„

3) ๊ฒฝ๋กœ ์—ด๊ฑฐ ๋ชจ๋ธ

๊ฐฑ์‹ ์ด ๊ฑฐ์˜ ๋ฐœ์ƒํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์œ ์šฉํ•œ ๋ฐฉ๋ฒ•

 

์ค‘์ฒฉ ์ง‘ํ•ฉ ๋ชจ๋ธ ์˜ˆ์‹œ

์ถ”๊ฐ€๋˜๋Š” ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋ ์ขŒํ‘œ(lft): (plft*2+prgt) / 3

์ถ”๊ฐ€๋˜๋Š” ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋ ์ขŒํ‘œ(rgt): (plft+prgt*2) / 3

๊ฐ€์žฅ ๊นŠ์€ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ์˜ ์›์„ ์ฐพ์œผ๋ฉด ๋จ

๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ์˜ ์›์€ ๋‹ค๋ฅธ ์–ด๋– ํ•œ ์›์—๋„ ํฌํ•จ๋˜์ง€ ์•Š์Œ

 

SELECT name, pcode
FROM PostalHistory2 PH1
WHERE name='A'
AND NOT EXISTS
    (SELECT * 
     FROM PostalHistory2 PH2
     WHERE PH2.name='A'
     AND Ph1.lft>Ph2.lft);

NOT EXISTS๋ฅผ ์‚ฌ์šฉํ•ด ์™ผ์ชฝ ๋์˜ ์ขŒํ‘œ๊ฐ€ ๋‹ค๋ฅธ ๋ชจ๋“  ์™ผ์ชฝ ๋ ์ขŒํ‘œ๋ณด๋‹ค ์ž‘๋„๋ก ์กฐ๊ฑด ๋ช…์‹œ

์žฌ๊ท€ ์—ฐ์‚ฐ ๋Œ€์‹  ์ค‘์ฒฉ ์ฝ”๋“œ ์‚ฌ์šฉ

๋ฐ”์ด์–ด์Šค์˜ ๊ณต์ฃ„

๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์—๋Š” ๊ฐ๊ฐ์˜ ์žฅ๋‹จ์  ์กด์žฌ

-> ์ง‘ํ•ฉ ์ง€ํ–ฅ ์‚ฌ๊ณ ๋ฐฉ์‹์ด SQL์˜ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์™€ ํŠœ๋‹ ๋ฐฉ๋ฒ• ํ™œ์šฉ์— ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•จ

๋Œ“๊ธ€