Skip to main content

๐Ÿฆš [SQL] 59413 ์ž…์–‘ ์‹œ๊ฐ ๊ตฌํ•˜๊ธฐ (2)

https://school.programmers.co.kr/learn/courses/30/lessons/59413

image.png

image.png

1. ๋ฌธ์ œ

ํ…Œ์ด๋ธ”

  • ANIMAL_OUTS(ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME)

์กฐ๊ฑด

  • 0์‹œ๋ถ€ํ„ฐ 23์‹œ๊นŒ์ง€ ๊ฐ ์‹œ๊ฐ„๋Œ€๋ณ„ ์ž…์–‘ ๊ฑด์ˆ˜(COUNT) ๊ตฌํ•˜๊ธฐ
  • ์ž…์–‘์ด ์—†๋Š” ์‹œ๊ฐ„๋Œ€๋Š” 0์œผ๋กœ ํ‘œ์‹œ
  • ๊ฒฐ๊ณผ๋Š” ์‹œ๊ฐ„๋Œ€(HOUR) ์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌ
  • DATETIME ์ปฌ๋Ÿผ์—์„œ ์‹œ๊ฐ„๋งŒ ์ถ”์ถœํ•ด์„œ ๊ณ„์‚ฐ

2. ์˜ค๋‹ต์ฟผ๋ฆฌ

2.1 ์ฒซ๋ฒˆ์งธ ์‹œ๋„

์ž…์–‘ ๊ธฐ๋ก์ด 0๊ฑด์ธ ์‹œ๊ฐ„๋Œ€ ๋ˆ„๋ฝ

-- ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”
SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
GROUP BY HOUR(DATETIME)
ORDER BY HOUR(DATETIME)

์ฒ˜์Œ์— ์ž‘์„ฑํ•œ SQL๋ฌธ์ด ํ‹€๋ฆฐ ์ด์œ ๋Š” 0~23์‹œ ์ค‘ ์ž…์–‘์ด ์—†๋Š” ์‹œ๊ฐ„๋Œ€๋„ ๊ฒฐ๊ณผ์— ํฌํ•จ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ๊ฒฐ๊ณผ ์ž…์–‘ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ์‹œ๊ฐ„๋งŒ ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. GROUP BY๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์กด์žฌํ•˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ ์ง‘๊ณ„ํ•ด์„œ, ์ž…์–‘ ๊ธฐ๋ก์ด ์—†๋Š” ์‹œ๊ฐ„๋Œ€๋Š” ๊ฒฐ๊ณผ์— ์•ˆ ๋‚˜ํƒ€๋‚œ๋‹ค๊ณ  ํ•œ๋‹ค.

image.png

๋ฌธ์ œ ์˜ˆ์‹œ์ฒ˜๋Ÿผ 0๊ฑด๋„ ํ‘œ์‹œํ•˜๋ ค๋ฉด ์‹œ๊ฐ„ ๋ฒ”์œ„๋ฅผ ๋งŒ๋“ค์–ด์„œ LEFT JOINํ•ด์•ผ ํ•œ๋‹ค.
LEFT JOINํ•˜๋ฉด ๋Œ€์ƒ์ด ๋˜๋Š” ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋Š” ๋ชจ๋‘ ์ถœ๋ ฅ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

2.2 ๋‘ ๋ฒˆ์งธ ์‹œ๋„

๋ณ€์ˆ˜ @HOUR๋ฅผ ํ•˜๋‚˜์”ฉ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ COUNT๋ฅผ ๋ฝ‘๋Š” ๋ฐฉ์‹

SET @HOUR = -1;
SELECT (@HOUR := @HOUR + 1) AS HOUR,
    (SELECT COUNT(HOUR(DATETIME))
     FROM ANIMAL_OUTS
     WHERE HOUR(DATETIME)=@HOUR) AS COUNT
     FROM ANIMAL_OUTS
WHERE @HOUR < 23;
  1. FROM ANIMAL_OUTS๋ฅผ ๋ถ™์—ฌ์„œ ์‚ฌ์‹ค์ƒ ํ…Œ์ด๋ธ”์˜ ํ–‰ ์ˆ˜๋งŒํผ ๋ฃจํ”„๊ฐ€ ๋„๋Š” ๊ตฌ์กฐ๋ผ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋งŽ์ด ๋ฐ˜๋ณต๋œ๋‹ค.
  2. WHERE @HOUR < 23 ์กฐ๊ฑด๋„ ํ…Œ์ด๋ธ” ํ–‰๋งˆ๋‹ค ๊ฒ€์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๋ณต๋œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  3. ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ COUNT(HOUR(DATETIME)) ๋Œ€์‹  COUNT(*)๊ฐ€ ๋” ์•ˆ์ „ํ•˜๋‹ค.

๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€์ˆ˜ + ์„œ๋ธŒ์ฟผ๋ฆฌ์— LIMIT ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊พธ๋ฉด ์„ฑ๋Šฅ์ด ์ข€ ๋‚ซ๋‹ค๊ณ  ํ•œ๋‹ค.

SET @HOUR := -1;

SELECT @HOUR := @HOUR + 1 AS HOUR,
       (SELECT COUNT(*)
        FROM ANIMAL_OUTS
        WHERE HOUR(DATETIME) = @HOUR) AS COUNT
FROM information_schema.COLUMNS
LIMIT 24;

3. ์ •๋‹ต์ฟผ๋ฆฌ

์ž…์–‘ ์‹œ๊ฐ ๊ตฌํ•˜๊ธฐ ๋ฌธ์ œ๋Š” ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

  1. UNION ALL ๋ฐฉ์‹
  2. ๋ณ€์ˆ˜(@HOUR) ๋ฐฉ์‹ - ๋ฃจํ”„ ํ‰๋‚ด
  3. WITH RECURSIVE ๋ฐฉ์‹ (MySQL 8 ์ด์ƒ) - ์ถ”์ฒœ

3.1 UNION ALL ๋ฐฉ์‹ (MySQL 5.x์—์„œ๋„ ๊ฐ€๋Šฅ)

  1. WITH hours AS (...)๋กœ 0~23์‹œ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ชจ๋“  ์‹œ๊ฐ„๋Œ€ ํฌํ•จํ•˜๊ธฐ
  2. LEFT JOIN์œผ๋กœ ์ž…์–‘ ๊ธฐ๋ก๊ณผ ์—ฐ๊ฒฐ, ๊ธฐ๋ก์ด ์—†์œผ๋ฉด NULL
  3. COALESCE๋กœ NULL์„ 0์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ
  4. GROUP BY ํ›„ ORDER BY๋กœ ์‹œ๊ฐ„์ˆœ ์ •๋ ฌ
SELECT h AS HOUR, 
       COALESCE(COUNT(a.DATETIME), 0) AS COUNT
FROM (
    SELECT 0 AS h UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
    UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
    UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11
    UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15
    UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19
    UNION ALL SELECT 20 UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23
) AS hours
LEFT JOIN ANIMAL_OUTS a 
       ON h = HOUR(a.DATETIME)
GROUP BY h
ORDER BY h;
  • COALESCE(COUNT(a.DATETIME), 0) โ†’ โ€œ์—†์œผ๋ฉด 0์œผ๋กœ ํ‘œ์‹œโ€
  • SELECT 0 AS h โ†’ โ€œ์‹œ๊ฐ„ ์ˆซ์ž(0)๋ฅผ ๋งŒ๋“ค๊ณ  ์—ด ์ด๋ฆ„์„ h๋ผ๊ณ  ๋ถ™์ž„โ€

UNION ALL ์ด ๊ธธ์–ด์„œ ๊ฐ€๋…์„ฑ์ด ์ข€ ๋–จ์–ด์ง€๊ธด ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด MySQL๋ฒ„์ „์— ์ƒ๊ด€ ์—†์ด ๋™์ž‘ํ•œ๋‹ค.


NULL ์ฒ˜๋ฆฌ

1๏ธโƒฃ COALESCE(COUNT(a.DATETIME), 0) AS COUNT

COUNT(a.DATETIME)

  • ํŠน์ • ์‹œ๊ฐ„๋Œ€์— ์ž…์–‘๋œ ๋™๋ฌผ ์ˆ˜๋ฅผ ์„ธ๋Š” ๊ฒƒ์ด๋‹ค.
  • LEFT JOIN์„ ํ–ˆ์„ ๋•Œ ํ•ด๋‹น ์‹œ๊ฐ„๋Œ€์— ์ž…์–‘์ด 1๊ฑด๋„ ์—†์œผ๋ฉด NULL์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž„..

COALESCE(๊ฐ’, ๋Œ€์ฒด๊ฐ’)

  • ์ฒซ ๋ฒˆ์งธ ๊ฐ’์ด NULL์ด๋ฉด ๋‘ ๋ฒˆ์งธ ๊ฐ’์„ ๋Œ€์‹  ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์ฆ‰, COUNT(a.DATETIME)์ด NULL์ผ ๊ฒฝ์šฐ 0์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

UNION ALL ์—ฐ์‚ฐ

2๏ธโƒฃ SELECT 0 AS h

์ด ๋ถ€๋ถ„์€ ์‹œ๊ฐ„ ์ˆซ์ž๋ฅผ ๊ฐ•์ œ๋กœ ๋งŒ๋“ค์–ด๋‚ด๋Š” ์ฝ”๋“œ์ด๋‹ค.

SELECT 0 AS h

โ†’ ์‹คํ–‰ํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ์ด๋ ‡๊ฒŒ ๋‚˜์˜จ๋‹ค.

h

0

์—ฌ๊ธฐ์—๋‹ค๊ฐ€

SELECT 0 AS h UNION ALL SELECT 1 UNION ALL SELECT 2

โ†’ ์‹คํ–‰ํ•˜๋ฉด

h

0

1

2

์ด๋ ‡๊ฒŒ 0, 1, 2โ€ฆ ์ˆซ์ž ๋ชฉ๋ก์„ ์ธ์œ„์ ์œผ๋กœ ๋งŒ๋“ค์–ด์„œ ANIMAL_OUTS ํ…Œ์ด๋ธ”๊ณผ JOINํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐœํŒ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.
์ฆ‰, "0์‹œ, 1์‹œ, 2์‹œ โ€ฆ 23์‹œ"๋ผ๋Š” ๋ชจ๋“  ์‹œ๊ฐ„๋Œ€๋ฅผ ๊ฐ•์ œ๋กœ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์—ญํ• ์ด๋‹ค.


3.2 ๋ณ€์ˆ˜(@HOUR) ๋ฐฉ์‹ (๋ฃจํ”„ ํ‰๋‚ด)

  1. SET @HOUR := -1; โ†’ ๋ณ€์ˆ˜ ์ค€๋น„
  2. SELECT @HOUR := @HOUR + 1 AS HOUR ... LIMIT 24;
    โ†’ @HOUR๊ฐ€ 0 โ†’ 1 โ†’ 2 โ€ฆ โ†’ 23๊นŒ์ง€ ์ž๋™ ์ฆ๊ฐ€
  3. (SELECT COUNT(*) FROM ANIMAL_OUTS WHERE HOUR(DATETIME) = @HOUR)
    โ†’ ํ•ด๋‹น ์‹œ๊ฐ„๋Œ€์˜ ์ž…์–‘ ๊ฑด์ˆ˜๋ฅผ ์„ธ์„œ ๊ฒฐ๊ณผ์— ๋ถ™์ž„
SET @HOUR := -1;

SELECT @HOUR := @HOUR + 1 AS HOUR,
       (SELECT COUNT(*)
        FROM ANIMAL_OUTS
        WHERE HOUR(DATETIME) = @HOUR) AS CNT
FROM (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
      UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8
      UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12
      UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16
      UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20
      UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23 UNION ALL SELECT 24) AS tmp;
  • ์ฝ”๋“œ๊ฐ€ ์งง์•„์„œ ํ™•์‹คํžˆ UNION ALL๋ณด๋‹ค ๊น”๋”ํ•˜๋‹ค.
  • information_schema.COLUMNS ๊ฐ™์€ ์‹œ์Šคํ…œ ํ…Œ์ด๋ธ”์„ ์ด์šฉํ•ด์„œ 24๋ฒˆ๋งŒ ๋ฃจํ”„๋ฅผ ๋Œ๋ฆฌ๋Š” ์›๋ฆฌ์ด๋‹ค.
  • ๋ฐ์ดํ„ฐ๋Ÿ‰๊ณผ ๊ด€๊ณ„์—†์ด ํ•ญ์ƒ 24ํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅํ•œ๋‹ค.
  • ํ•˜์ง€๋งŒ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์ด ๋‚ฏ์„ค์–ด์„œ ๋‚˜๊ฐ™์€ ์ดˆ๋ณด์ž๊ฐ€ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  • ๋‚˜๋„ SQL์—์„œ ์ด๋ ‡๊ฒŒ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฑธ ์˜ค๋‹ต์ •๋ฆฌ ํ•˜๋ฉด์„œ ์ฒ˜์Œ ๋ณด์•˜๋‹ค.

1๏ธโƒฃ SET @HOUR := -1;

  • ์—ฌ๊ธฐ์„œ @HOUR๋Š” ์‚ฌ์šฉ์ž ๋ณ€์ˆ˜(User-defined variable)์ด๋‹ค.
  • MySQL์—์„œ @๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฑด ์„ธ์…˜ ๋‹จ์œ„ ๋ณ€์ˆ˜๋ผ์„œ ์ฟผ๋ฆฌ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ๋งŒ ์‚ด์•„ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.
  • SET @HOUR := -1; ์€ @HOUR๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ -1๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.
  • "์ด์ œ๋ถ€ํ„ฐ @HOUR๋ผ๋Š” ์ด๋ฆ„์˜ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ๊ฐ’์€ -1๋กœ ๋„ฃ์–ด๋‘˜๊ฒŒ" ๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ์‰ฝ๋‹ค.

2๏ธโƒฃ := ์—ฐ์‚ฐ์ž

MySQL์—์„œ๋Š” =๋„ ๋Œ€์ž… ์—ฐ์‚ฐ์ž๋กœ ์“ฐ์ด์ง€๋งŒ, :=์„ ์“ฐ๋Š” ๊ฒŒ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ โ€œ๊ฐ’์„ ๋ณ€์ˆ˜์— ๋Œ€์ž…ํ•œ๋‹คโ€๋Š” ์˜๋ฏธ๋ผ๊ณ  ํ•œ๋‹ค.

SET @num := 10;

โ†’ ๋ณ€์ˆ˜ @num์— 10์„ ๋„ฃ์–ด๋ผ.


3๏ธโƒฃ @HOUR := @HOUR + 1 AS HOUR

  • ์ด๊ฑด ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค @HOUR ๊ฐ’์„ 1์”ฉ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ํŠธ๋ฆญ์ด๋‹ค.
  • ์ฒ˜์Œ์— @HOUR = -1๋กœ ์„ธํŒ…ํ–ˆ์œผ๋‹ˆ๊นŒ, ์ฒซ ๋ฒˆ์งธ ์‹คํ–‰์—์„œ @HOUR := -1 + 1 = 0 โ†’ ๊ฒฐ๊ณผ HOUR = 0
  • ๋‘ ๋ฒˆ์งธ ์‹คํ–‰์—์„œ @HOUR := 0 + 1 = 1 โ†’ ๊ฒฐ๊ณผ HOUR = 1
  • โ€ฆ ์ด๋ ‡๊ฒŒ ๊ณ„์† ์˜ฌ๋ผ๊ฐ€์„œ 23๊นŒ์ง€ ์ถœ๋ ฅ๋œ๋‹ค.
  • ๊ทธ๋ž˜์„œ LIMIT 24๋ฅผ ๋ถ™์—ฌ์„œ ๋”ฑ 0~23๊นŒ์ง€๋งŒ ๋‚˜์˜ค๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

3.3 WITH RECURSIVE ๋ฐฉ์‹ (MySQL 8 ์ด์ƒ)

WITH RECURSIVE hours AS (
    SELECT 0 AS HOUR
    UNION ALL
    SELECT HOUR + 1 FROM hours WHERE HOUR < 23
)
SELECT h.HOUR,
       COALESCE(COUNT(a.DATETIME), 0) AS COUNT
FROM hours h
LEFT JOIN ANIMAL_OUTS a 
       ON h.HOUR = HOUR(a.DATETIME)
GROUP BY h.HOUR
ORDER BY h.HOUR;

MySQL 8 ์ด์ƒ์—์„œ๋งŒ ์ง€์›ํ•˜๋Š” ๋ฐฉ์‹์ธ๋ฐ, ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š๊ณ ๋„ ์ˆซ์ž๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ์ž๋™ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด์„œ ๊ฐ€์žฅ ๊น”๋”ํ•˜๋‹ค. WITH RECURSIVE๋Š” ์žฌ๊ท€์  CTE(Common Table Expression)๋ฅผ ๋งŒ๋“œ๋Š” ๊ตฌ๋ฌธ์ด๋‹ค. ์ฆ‰, ์ž„์‹œ ํ…Œ์ด๋ธ”(hours)์„ ๋งŒ๋“ค๊ณ  ๊ทธ ์•ˆ์—์„œ ์ž๊ธฐ ์ž์‹ ์„ ๋‹ค์‹œ ์ฐธ์กฐํ•˜๋ฉด์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. MySQL ๋ฒ„์ „์ด ๋‚ฎ์ง€ ์•Š์œผ๋ฉด ๊ฐ€์žฅ ์ถ”์ฒœ๋˜๋Š” ๊น”๋”ํ•œ ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค.

์ž๋ฐ” for๋ฌธ์„ ๋– ์˜ฌ๋ฆฌ๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค. โ€œ0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ 1์”ฉ ์ฆ๊ฐ€์‹œํ‚ค๋ฉฐ 23๊นŒ์ง€ ์ˆซ์ž ๋ชฉ๋ก์„ ๋งŒ๋“ค์–ด๋ผโ€ ๋ผ๋Š” ๋กœ์ง์„ SQL๋กœ ์˜ฎ๊ฒจ๋†“์€ ๊ฒƒ๊ณผ ๊ฐ™๋‹ค.


1๏ธโƒฃ WITH RECURSIVE hours AS (...)

  • WITH RECURSIVE๋Š” ์žฌ๊ท€์  CTE(Common Table Expression)๋ฅผ ๋งŒ๋“ ๋‹ค๋Š” ๋œป์ด๋‹ค.
  • ์ฆ‰, ์ž„์‹œ ํ…Œ์ด๋ธ”(hours)์„ ๋งŒ๋“ค๊ณ , ๊ทธ ์•ˆ์—์„œ ์ž๊ธฐ ์ž์‹ ์„ ๋‹ค์‹œ ์ฐธ์กฐํ•ด์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด๋‹ค.

2๏ธโƒฃ SELECT 0 AS HOUR

  • ์žฌ๊ท€์˜ ์‹œ์ž‘(Anchor part)์ด๋‹ค.
  • ์—ฌ๊ธฐ์„œ 0์ด๋ผ๋Š” ๊ฐ’์„ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ , ๊ทธ ์—ด ์ด๋ฆ„์„ HOUR๋ผ๊ณ  ๋ถ™์ธ๋‹ค.
  • ๊ฒฐ๊ณผ:

HOUR

0


3๏ธโƒฃ UNION ALL

  • ์ฒซ ๋ฒˆ์งธ ๊ฒฐ๊ณผ(0)์™€ ๋’ค์— ๋‚˜์˜ค๋Š” ์žฌ๊ท€ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํ•ฉ์นœ๋‹ค.
  • UNION์€ ์ค‘๋ณต ์ œ๊ฑฐ๋ฅผ ํ•˜์ง€๋งŒ, UNION ALL์€ ์ค‘๋ณต๋„ ๋‹ค ํฌํ•จ์‹œํ‚จ๋‹ค.
  • ์—ฌ๊ธฐ์„œ๋Š” ์ค‘๋ณต ๊ฑฑ์ • ์—†์œผ๋‹ˆ๊นŒ UNION ALL์„ ์“ฐ๋Š” ๊ฒŒ ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•˜๋‹ค.

4๏ธโƒฃ SELECT HOUR + 1 FROM hours WHERE HOUR < 23

  • ์žฌ๊ท€ ๋ถ€๋ถ„(Recursive part)์ด๋‹ค.
  • ๋ฐฉ๊ธˆ ๋งŒ๋“  hours ์ž„์‹œ ํ…Œ์ด๋ธ”์—์„œ HOUR ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์„œ +1์„ ํ•ด์คŒ
  • ๊ทธ๋ฆฌ๊ณ  WHERE HOUR < 23 ์กฐ๊ฑด์œผ๋กœ 23๊นŒ์ง€๋งŒ ์ƒ์„ฑ๋˜๊ฒŒ ์ œํ•œํ•œ๋‹ค.

๋™์ž‘ ํ๋ฆ„์„ ๋ณด์ž:

  1. ์ฒ˜์Œ์—๋Š” 0์ด ๋‚˜์˜ด (Anchor part)
  2. hours ํ…Œ์ด๋ธ”์— 0์ด ์žˆ์œผ๋‹ˆ โ†’ 0+1=1 ์ƒ์„ฑ
  3. hours ํ…Œ์ด๋ธ”์— 1์ด ์žˆ์œผ๋‹ˆ โ†’ 1+1=2 ์ƒ์„ฑ
  4. โ€ฆ ๋ฐ˜๋ณต โ€ฆ
  5. 23๊นŒ์ง€ ์˜ค๋ฉด 23 < 23 ์กฐ๊ฑด์ด false โ†’ ๋ฉˆ์ถค
    โ†’ ์—ฌ๊ธฐ์„œ <24๊ฐ€ ์•„๋‹ˆ๋ผ <23๊นŒ์ง€ ํ•ด์•ผ 23์‹œ๊นŒ์ง€ ์ถœ๋ ฅ๋˜๋‹ค๋Š” ๊ฒƒ์ด ์•ฝ๊ฐ„ ํ—ท๊ฐˆ๋ฆฐ๋‹ค.
  6. ์ด ๊ณผ์ •์„ ๋‹ค ๊ฑฐ์น˜๋ฉด hours๋ผ๋Š” CTE์—๋Š” 0๋ถ€ํ„ฐ 23๊นŒ์ง€ ์ˆซ์ž๊ฐ€ ์ƒ๊ธด๋‹ค.