๐Ÿ—๏ธPROGRAMMERS/SQL

[SQL] ๋ฉธ์ข…์œ„๊ธฐ์˜ ๋Œ€์žฅ๊ท  ์ฐพ๊ธฐ

๋น™๋””์šฉ 2024. 4. 19.

์‹œ์šฉ์–ธ์–ด : MYSQL

LEVEL : 5

๋ฌธ์ œ : ๋ฉธ์ข…์œ„๊ธฐ์˜ ๋Œ€์žฅ๊ท  ์ฐพ๊ธฐ

 

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

programmers.co.kr

๋ฌธ์ œํ’€์ด

WITH RECURSIVE generations AS (
    SELECT id,
        COALESCE(parent_id, 0) AS parent_id,
        1 AS generation
    FROM ECOLI_DATA
    WHERE parent_id IS NULL
    UNION ALL
    SELECT
        E.id,
        E.parent_id,
        G.generation + 1 AS generation
    FROM ECOLI_DATA E
    JOIN generations G
    ON E.parent_id = G.id
)
SELECT
    COUNT(*) AS count,
    G.generation AS generation
FROM generations G
LEFT JOIN ECOLI_DATA E
ON G.id = E.parent_id
WHERE E.id IS NULL
GROUP BY G.generation
ORDER BY G.generation;

- ์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด์˜ ์ˆ˜๋ฅผ ๊ฐ ์„ธ๋Œ€๋ณ„๋กœ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ECOLI_DATA ํ…Œ์ด๋ธ”์˜ ์ •๋ณด๋ฅผ ์„ธ๋Œ€๋ณ„๋กœ ๊ทธ๋ฃนํ™” ํ•œ ๋’ค, ๊ฐ ๊ทธ๋ฃน์—์„œ ์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด์˜ ์ˆ˜๋ฅผ ์„ธ์–ด์•ผ ํ•œ๋‹ค.

- ๋˜ํ•œ ๊ฐ ๊ฐœ์ฒด์˜ ์„ธ๋Œ€๋Š” ๋ถ€๋ชจ ๊ฐœ์ฒด์˜ ์„ธ๋Œ€๋ณด๋‹ค 1๋งŒํผ ๋†’์•„์•ผํ•œ๋‹ค.(์ดˆ๊ธฐ ๊ฐœ์ฒด์˜ ์„ธ๋Œ€๋Š” 1)

 

<๊ฐ ๊ฐœ์ฒด์˜ ์„ธ๋Œ€๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•>

- ๊ฐ ๊ฐœ์ฒด๊ฐ€ ์–ด๋Š ์„ธ๋Œ€์— ์†ํ•˜๋Š”์ง€๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์žฌ๊ท€์  ์กฐ์ธ์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ ๊ฐœ์ฒด์˜ ๋ถ€๋ชจ ์ž์‹ ๊ด€๊ณ„๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ์„ธ๋Œ€๋ฅผ ๊ณ„์‚ฐํ•ด์•ผํ•œ๋‹ค. (WITH RECURSIVE๋ฌธ ์‚ฌ์šฉ)

์ฐธ๊ณ  - Inpa DeV

 

1. ์กฐ๊ฑด ์„ค์ •

- SELECT ์ ˆ์—์„œ๋Š” id, COALESCE(parent_id, 0) AS parent_id, 1 AS generation์„ ์„ ํƒํ•œ๋‹ค. (์ดˆ๊ธฐ ๊ฐœ์ฒด๋“ค์˜ ์„ธ๋Œ€๋Š” 1๋กœ ์„ค์ •)

- WHERE ์ ˆ์—์„œ๋Š” parent_id IS NULL ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋ชจ ๊ฐœ์ฒด๊ฐ€ ์—†๋Š”(์ฆ‰, parent_id๊ฐ€ NULL์ธ) ์ดˆ๊ธฐ ๊ฐœ์ฒด๋“ค์„ ์„ ํƒํ•œ๋‹ค.

- ์ดˆ๊ธฐ ๊ฐœ์ฒด๋“ค์€ ์„ธ๋Œ€์˜ ์‹œ์ž‘์ ์ด๋ฏ€๋กœ generation์„ 1๋กœ ์„ค์ •

 

2. ์žฌ๊ท€ ๋‹จ๊ณ„

- UNION ALL์„ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐ ์กฐ๊ฑด๊ณผ ์žฌ๊ท€์ ์œผ๋กœ ์กฐ์ธ๋œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์žฅ

- JOIN์„ ์‚ฌ์šฉํ•˜์—ฌ ECOLI_DATA๊ณผ generations CTE๋ฅผ ์กฐ์ธ (์ž์‹ ๊ฐœ์ฒด์˜ parent_id์™€ ๋ถ€๋ชจ ๊ฐœ์ฒด์˜ id)

    *CTE( Common Table Expressions)๋ณต์žกํ•œ SQL ์ฟผ๋ฆฌ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ผ์‹œ์ ์ธ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์œผ๋กœ, ์ฟผ๋ฆฌ ์‹คํ–‰                                                                  ์‹œ ํ•œ๋ฒˆ ์ •์˜๋œ๋‹ค.

- ์กฐ์ธ๋œ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด ๋ถ€๋ชจ ๊ฐ์ฒด์˜ generation์— 1์„ ๋”ํ•ด ์ž์‹ ๊ฐ์ฒด์˜ generation์„ ๊ณ„์‚ฐ

 

3. ์ข…๋ฃŒ

- ๋” ์ด์ƒ ์ƒˆ๋กœ์šด ๊ฐœ์ฒด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์žฌ๊ท€ ์กฐ์ธ์ด ์ข…๋ฃŒ

 

<์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด ์ฐพ๋Š” ๋ฐฉ๋ฒ•>

- ์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์€ LEFT JOIN์„ ํ†ตํ•ด ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1. ์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด ์‹๋ณ„

- LEFT JOIN์„ ์‚ฌ์šฉํ•˜์—ฌ ECOLI_DATA ํ…Œ์ด๋ธ”์„ ์กฐ์ธ(๊ฐ ๊ฐœ์ฒด์˜ ID๊ฐ€ ๋‹ค๋ฅธ ๊ฐœ์ฒด์˜ PARENT_ID์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ)

- LEFT JOIN์„ ํ†ตํ•ด ๋ถ€๋ชจ ๊ฐœ์ฒด์˜ ID์— ์ƒ์‘ํ•˜๋Š” ์ž์‹ ๊ฐœ์ฒด์˜ ID๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๊ฒฝ์šฐ NULL๋กœ ํ‘œ์‹œ๋˜๋Š”๋ฐ, ์ด๋Š” ์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

2. ์ƒˆ๋Œ€๋ณ„ ๊ทธ๋ฃนํ™” / ๊ณ„์‚ฐ

- ์•ž์—์„œ ์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด๋ฅผ ์‹๋ณ„ํ•œ ๋’ค GROUP BY๋ฅผ ํ†ตํ•ด ์„ธ๋Œ€๋ณ„๋กœ ๊ทธ๋ฃนํ™”

- ๊ฐ ๊ทธ๋ฃน์—์„œ COUNT(*)๋ฅผ ์‚ฌ์šฉํ•ด ์ž์‹์ด ์—†๋Š” ๊ฐœ์ฒด์˜ ์ˆ˜๋ฅผ ๊ณ„์‚ฐ

 

3. ์ตœ์ข… ์ •๋ ฌ

- GROUP BY๋ฅผ ์‚ฌ์šฉํ•ด ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ

ํ›„๊ธฐ

- ์žฌ๊ท€ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•œ ๋ฌธ์ œ์˜€๋‹ค.

๋Œ“๊ธ€