CTE

Common Table Expression ์˜ ์•ฝ์ž๋กœ ๊ณตํ†ต ํ…Œ์ด๋ธ” ํ‘œํ˜„์‹์ด๋‹ค.

๋ช…๋ น๋ฌธ ๋‚ด์—์„œ ์ž„์‹œ๋กœ ์ƒ์„ฑํ•œ ํ…Œ์ด๋ธ”๋กœ ์ฟผ๋ฆฌ ์‹คํ–‰ ์ค‘์—๋งŒ ์ง€์†๋˜๊ณ  ํŒŒ์ƒํƒœ์ด๋ธ”๊ณผ ๋‹ฌ๋ฆฌ ์ฟผ๋ฆฌ ์‹คํ–‰ ์ค‘์— ์—ฌ๋Ÿฌ๋ฒˆ ์ฐธ์กฐ ๋  ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ๋ณธ ๊ตฌ๋ฌธ

WITH cte_name (column_list) AS (
    query
)
SELECT * FROM cte_name;

WITH AS ์ ˆ์„ ์ด์šฉํ•˜์—ฌ ()์•ˆ์˜ ์ฟผ๋ฆฌ๋ฌธ[Select from where]์„ ์ด์šฉํ•ด ์ž„์‹œ ํ…Œ์ด๋ธ” cte_name์„ ๋งŒ๋“ค์–ด ์ด CTE์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์˜ˆ์‹œ ๊ตฌ๋ฌธ

WITH topsales2003 AS (
    SELECT
        salesRepEmployeeNumber employeeNumber,
        SUM(quantityOrdered * priceEach) sales
    FROM
        orders
            INNER JOIN
        orderdetails USING (orderNumber)
            INNER JOIN
        customers USING (customerNumber)
    WHERE
        YEAR(shippedDate) = 2003
            AND status = 'Shipped'
    GROUP BY salesRepEmployeeNumber
    ORDER BY sales DESC
    LIMIT 5
)
SELECT
    employeeNumber,
    firstName,
    lastName,
    sales
FROM
    employees
    JOIN
    topsales2003 USING (employeeNumber);

orders, orderdetails, customers ์„ธ๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ joinํ•œ CTE๋ฅผ employees์™€ joinํ•˜์—ฌ selectํ•˜๋Š” ์ฟผ๋ฆฌ๋ฌธ

์žฌ๊ท€์  CTE (RECURSIVE CTE)

Mysql 8.0์ด์ƒ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , anchor member(์žฌ๊ท€ ๋ฉค๋ฒ„,column)๋ฅผ ์žฌ๊ท€ ์กฐ๊ฑด์—์— ๋”ฐ๋ผ ๋ฐ˜๋ณตํ•˜๋ฉฐ UNION ALL, UNION DISTINCT์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ์žฌ๊ท€ ๋งด๋ฒ„๋“ค์„ ํ•ฉ์นœ TABLE์„ ์ƒ์„ฑํ•œ๋‹ค.

์˜ˆ์‹œ ๊ตฌ๋ฌธ

WITH RECURSIVE cte_name AS (
    initial_query  -- anchor member
    UNION ALL
    recursive_query -- recursive member that references to the CTE name
)
SELECT * FROM cte_name;

์žฌ๊ท€ ๋ฉค๋ฒ„๋Š” ์ง‘๊ณ„ํ•จ์ˆ˜(MAX,MIN,SUM,AVG,COUNT..), GROUP BY, ORDER BY, LIMIT, DISTINCT ๋ฅผ ํฌํ•จ ํ•  ์ˆ˜ ์—†๋‹ค. (UNION DISTINCT๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ DISTINCT๋Š” ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค)

์‚ฌ์šฉ ์˜ˆ์‹œ ๊ตฌ๋ฌธ

WITH RECURSIVE
    cte AS (
        SELECT 0 AS HOUR
        UNION ALL
        SELECT HOUR + 1
        FROM cte
        WHERE HOUR <23)
SELECT
   hour, count(o.datetime)

FROM
    cte
left JOIN ANIMAL_OUTS AS O
ON cte.hour = HOUR(O.DATETIME)
group by hour;

์ˆซ์ž 0๋ถ€ํ„ฐ 23๊นŒ์ง€ 1์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” COLUMN(HOUR)๋ฅผ ๊ฐ€์ง„ TABLE (CTE)๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ด cte์™€ animal_outs๋ผ๋Š” ํ…Œ์ด๋ธ”๊ณผ joinํ•œ ์ฟผ๋ฆฌ๋ฌธ์ด๋‹ค.

WITH RECURSIVE employee_paths AS
  ( SELECT employeeNumber,
           reportsTo managerNumber,
           officeCode,
           1 lvl
   FROM employees
   WHERE reportsTo IS NULL
     UNION ALL
     SELECT e.employeeNumber,
            e.reportsTo,
            e.officeCode,
            lvl+1
     FROM employees e
     INNER JOIN employee_paths ep ON ep.employeeNumber = e.reportsTo )
SELECT employeeNumber,
       managerNumber,
       lvl,
       city
FROM employee_paths ep
INNER JOIN offices o USING (officeCode)
ORDER BY lvl, city;

employeesํ…Œ์ด๋ธ”์—์„œ reportsTo๊ฐ€ NULL์ธ row๋ฅผ ์‹œ์ž‘์œผ๋กœ ํ•ด๋‹น row์˜ employeeNumber์™€ ๊ฐ™์€ ๊ฐ’์˜ reportsTo๋ฅผ ๊ฐ–๋Š” row๋“ค์„ lvl์„ ์ฆ๊ฐ€ ์‹œํ‚ค๊ณ  ์ด row์— ๋Œ€ํ•ด ๋˜ ๋น„๊ตํ•˜๋ฉฐ ์žฌ๊ท€์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜์—ฌ employeeNumber์™€ ๊ฐ™์€ reportsTo์˜ ๊ฐ’์„ ๊ฐ–๋Š” row๊ฐ€ ์—†์„๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜์—ฌ cte๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

์ด ์ƒ์„ฑํ•œ cte์™€ offices ํ…Œ์ด๋ธ”์„ joinํ•˜์—ฌ selectํ•˜๋Š” ์ฟผ๋ฆฌ๋ฌธ์ด๋‹ค.

Last updated