ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CTE(Common Table Expression) ์™„๋ฒฝ ์ดํ•ด ๊ฐ€์ด๋“œ
    Programing Language/SQL 2025. 6. 13. 22:45
    ๋ฐ˜์‘ํ˜•

    ๐ŸŽฏ CTE๋ž€?

    **CTE (Common Table Expression)**๋Š” **"์ž„์‹œ ํ…Œ์ด๋ธ”"**์„ ๋งŒ๋“œ๋Š” SQL ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค.

    ์‰ฌ์šด ๋น„์œ 

    • ์„œ๋ธŒ์ฟผ๋ฆฌ์˜ ์—…๊ทธ๋ ˆ์ด๋“œ ๋ฒ„์ „
    • ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์ค‘๊ฐ„ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ณ  ์žฌ์‚ฌ์šฉ
    • ํ•จ์ˆ˜์ฒ˜๋Ÿผ ๋ณต์žกํ•œ ๋กœ์ง์„ ๋‹จ์ˆœํ™”

    ๐Ÿ“ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

     
    sql
    WITH ์ž„์‹œํ…Œ์ด๋ธ”๋ช… AS (
        SELECT ์ฟผ๋ฆฌ...
    )
    SELECT * FROM ์ž„์‹œํ…Œ์ด๋ธ”๋ช…;

    ์‹ค์ œ ์˜ˆ์‹œ

     
    sql
    -- ๊ธฐ์กด ๋ณต์žกํ•œ ์ฟผ๋ฆฌ
    SELECT *
    FROM (
        SELECT customer_id, SUM(amount) as total
        FROM orders 
        WHERE order_date >= '2023-01-01'
        GROUP BY customer_id
    ) sub
    WHERE total > 1000;
    
    -- CTE๋กœ ๊น”๋”ํ•˜๊ฒŒ
    WITH customer_totals AS (
        SELECT customer_id, SUM(amount) as total
        FROM orders 
        WHERE order_date >= '2023-01-01'
        GROUP BY customer_id
    )
    SELECT *
    FROM customer_totals
    WHERE total > 1000;

    ๐Ÿ”„ CTE vs ์„œ๋ธŒ์ฟผ๋ฆฌ ๋น„๊ต

    ์„œ๋ธŒ์ฟผ๋ฆฌ ๋ฐฉ์‹ (๋ณต์žกํ•จ)

     
    sql
    -- ์„œ๋ธŒ์ฟผ๋ฆฌ: ์ฝ๊ธฐ ์–ด๋ ค์›€
    SELECT c.name, o.total_amount
    FROM customers c
    INNER JOIN (
        SELECT customer_id, SUM(amount) as total_amount
        FROM orders
        WHERE status = 'completed'
        GROUP BY customer_id
    ) o ON c.id = o.customer_id
    WHERE o.total_amount > 500;

    CTE ๋ฐฉ์‹ (๊น”๋”ํ•จ)

     
    sql
    -- CTE: ์ฝ๊ธฐ ์‰ฌ์›€
    WITH completed_orders AS (
        SELECT customer_id, SUM(amount) as total_amount
        FROM orders
        WHERE status = 'completed'
        GROUP BY customer_id
    )
    SELECT c.name, co.total_amount
    FROM customers c
    INNER JOIN completed_orders co ON c.id = co.customer_id
    WHERE co.total_amount > 500;

    ๐Ÿš€ CTE์˜ ์žฅ์ 

    1. ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ

     
    sql
    -- ๋‹จ๊ณ„๋ณ„ ๋ช…ํ™•ํ•œ ๋กœ์ง
    WITH step1 AS (๋ฐ์ดํ„ฐ ์ถ”์ถœ),
         step2 AS (๋ฐ์ดํ„ฐ ๊ฐ€๊ณต),
         step3 AS (์ตœ์ข… ์ง‘๊ณ„)
    SELECT * FROM step3;

    2. ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ

     
    sql
    WITH popular_products AS (
        SELECT product_id, COUNT(*) as order_count
        FROM orders
        GROUP BY product_id
        HAVING COUNT(*) > 100
    )
    -- ๊ฐ™์€ CTE๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    SELECT p1.product_id, p1.order_count
    FROM popular_products p1
    UNION ALL
    SELECT p2.product_id, p2.order_count  
    FROM popular_products p2
    WHERE p2.order_count > 200;

    3. ๋ณต์žกํ•œ ๋กœ์ง ๋‹จ์ˆœํ™”

     
    sql
    WITH 
    -- 1๋‹จ๊ณ„: ์›”๋ณ„ ๋งค์ถœ
    monthly_sales AS (
        SELECT DATE_FORMAT(order_date, '%Y-%m') as month,
               SUM(amount) as monthly_total
        FROM orders
        GROUP BY DATE_FORMAT(order_date, '%Y-%m')
    ),
    -- 2๋‹จ๊ณ„: ์ „์›” ๋Œ€๋น„ ์ฆ๊ฐ
    sales_growth AS (
        SELECT month, monthly_total,
               LAG(monthly_total) OVER (ORDER BY month) as prev_month,
               monthly_total - LAG(monthly_total) OVER (ORDER BY month) as growth
        FROM monthly_sales
    )
    -- 3๋‹จ๊ณ„: ์ตœ์ข… ๊ฒฐ๊ณผ
    SELECT month, monthly_total, growth,
           ROUND(growth / prev_month * 100, 2) as growth_rate
    FROM sales_growth
    WHERE prev_month IS NOT NULL;

    ๐Ÿ”ข CTE ์œ ํ˜•๋ณ„ ์„ค๋ช…

    1. ์ผ๋ฐ˜ CTE (Single CTE)

     
    sql
    WITH high_value_customers AS (
        SELECT customer_id, SUM(amount) as total_spent
        FROM orders
        GROUP BY customer_id
        HAVING SUM(amount) > 1000
    )
    SELECT c.name, hvc.total_spent
    FROM customers c
    INNER JOIN high_value_customers hvc ON c.id = hvc.customer_id;

    2. ๋‹ค์ค‘ CTE (Multiple CTEs)

     
    sql
    WITH 
    sales_2023 AS (
        SELECT * FROM orders WHERE YEAR(order_date) = 2023
    ),
    top_customers AS (
        SELECT customer_id, SUM(amount) as total
        FROM sales_2023
        GROUP BY customer_id
        ORDER BY total DESC
        LIMIT 10
    )
    SELECT * FROM top_customers;

    3. ์žฌ๊ท€ CTE (Recursive CTE)

     
    sql
    WITH RECURSIVE countdown AS (
        -- ์‹œ์ž‘๊ฐ’
        SELECT 10 as num
        
        UNION ALL
        
        -- ์žฌ๊ท€ ๋ถ€๋ถ„  
        SELECT num - 1
        FROM countdown
        WHERE num > 1
    )
    SELECT * FROM countdown;
    -- ๊ฒฐ๊ณผ: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

    ๐Ÿ’ผ ์‹ค๋ฌด ํ™œ์šฉ ์‚ฌ๋ก€

    1. ๊ณ ๊ฐ ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜

     
    sql
    WITH customer_metrics AS (
        SELECT 
            customer_id,
            COUNT(*) as order_count,
            SUM(amount) as total_spent,
            AVG(amount) as avg_order_value,
            MAX(order_date) as last_order_date
        FROM orders
        GROUP BY customer_id
    ),
    customer_segments AS (
        SELECT *,
            CASE 
                WHEN total_spent > 5000 AND order_count > 10 THEN 'VIP'
                WHEN total_spent > 1000 THEN 'Premium'
                WHEN order_count > 5 THEN 'Regular'
                ELSE 'New'
            END as segment
        FROM customer_metrics
    )
    SELECT segment, COUNT(*) as customer_count,
           AVG(total_spent) as avg_spent
    FROM customer_segments
    GROUP BY segment;

    2. ๋งค์ถœ ๋ถ„์„ ๋Œ€์‹œ๋ณด๋“œ

     
    sql
    WITH 
    daily_sales AS (
        SELECT DATE(order_date) as sale_date,
               SUM(amount) as daily_total
        FROM orders
        WHERE order_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
        GROUP BY DATE(order_date)
    ),
    moving_average AS (
        SELECT sale_date, daily_total,
               AVG(daily_total) OVER (
                   ORDER BY sale_date 
                   ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
               ) as ma_7day
        FROM daily_sales
    )
    SELECT sale_date, daily_total, ma_7day,
           daily_total - ma_7day as variance
    FROM moving_average
    ORDER BY sale_date DESC;

    ๐ŸŽฏ ์ฝ”๋”ฉํ…Œ์ŠคํŠธ์—์„œ์˜ CTE

    ์ž์ฃผ ์ถœ์ œ๋˜๋Š” ํŒจํ„ด

    1. ๊ณ„์ธต ๊ตฌ์กฐ ๋ถ„์„

     
    sql
    -- ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ƒํ’ˆ ๋ถ„์„
    WITH category_hierarchy AS (
        -- Recursive CTE๋กœ ์นดํ…Œ๊ณ ๋ฆฌ ํŠธ๋ฆฌ ์ƒ์„ฑ
    ),
    sales_by_category AS (
        -- ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋งค์ถœ ์ง‘๊ณ„
    )
    SELECT * FROM sales_by_category;

    2. ์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ ๋ถ„์„

     
    sql
    -- ์›”๋ณ„ ์„ฑ์žฅ๋ฅ  ๋ถ„์„
    WITH monthly_metrics AS (
        -- ์›”๋ณ„ ์ง€ํ‘œ ๊ณ„์‚ฐ
    ),
    growth_analysis AS (
        -- ์ „์›” ๋Œ€๋น„ ์ฆ๊ฐ๋ฅ  ๊ณ„์‚ฐ
    )
    SELECT * FROM growth_analysis;

    3. ๋ณต์žกํ•œ ํ•„ํ„ฐ๋ง

     
    sql
    -- ์กฐ๊ฑด๋ถ€ ๊ณ ๊ฐ ๋ถ„์„
    WITH qualified_customers AS (
        -- 1์ฐจ ํ•„ํ„ฐ๋ง
    ),
    final_analysis AS (
        -- 2์ฐจ ๊ฐ€๊ณต
    )
    SELECT * FROM final_analysis;

    โšก CTE ์„ฑ๋Šฅ ํŒ

    โœ… ์ข‹์€ ์‚ฌ์šฉ

     
    sql
    -- ์ธ๋ฑ์Šค ํ™œ์šฉ ๊ฐ€๋Šฅํ•œ ์กฐ๊ฑด
    WITH filtered_data AS (
        SELECT * FROM large_table
        WHERE indexed_column = 'value'  -- ์ธ๋ฑ์Šค ํ™œ์šฉ
        AND date_column >= '2023-01-01'
    )

    โŒ ํ”ผํ•ด์•ผ ํ•  ์‚ฌ์šฉ

     
    sql
    -- ์ „์ฒด ํ…Œ์ด๋ธ” ์Šค์บ” ์œ ๋ฐœ
    WITH all_data AS (
        SELECT * FROM large_table  -- ๋„ˆ๋ฌด ํฐ ์ค‘๊ฐ„ ๊ฒฐ๊ณผ์…‹
    )

    ๐Ÿ”ง ์ตœ์ ํ™” ๋ฐฉ๋ฒ•

     
    sql
    -- 1. ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ ์„ ํƒ
    WITH optimized AS (
        SELECT id, amount, date_column  -- ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ
        FROM orders
        WHERE date_column >= '2023-01-01'  -- ์กฐ๊ธฐ ํ•„ํ„ฐ๋ง
    )
    
    -- 2. ๋‹จ๊ณ„๋ณ„ ํ•„ํ„ฐ๋ง
    WITH step1 AS (
        SELECT * FROM table1 WHERE condition1  -- 1์ฐจ ํ•„ํ„ฐ
    ),
    step2 AS (
        SELECT * FROM step1 WHERE condition2   -- 2์ฐจ ํ•„ํ„ฐ
    )

    ๐Ÿ† CTE ๋งˆ์Šคํ„ฐ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

    ์ดˆ๊ธ‰ → ์ค‘๊ธ‰

    • โœ… ๊ธฐ๋ณธ CTE ๋ฌธ๋ฒ• ์ดํ•ด
    • โœ… ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ CTE๋กœ ๋ณ€ํ™˜ ๊ฐ€๋Šฅ
    • โœ… ๋‹ค์ค‘ CTE ์‚ฌ์šฉ ๊ฐ€๋Šฅ

    ์ค‘๊ธ‰ → ๊ณ ๊ธ‰

    • โœ… Recursive CTE ํ™œ์šฉ
    • โœ… ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ CTE๋กœ ๊ตฌ์กฐํ™”
    • โœ… ์„ฑ๋Šฅ์„ ๊ณ ๋ คํ•œ CTE ์„ค๊ณ„

    ์ฟ ํŒก BA ๋ ˆ๋ฒจ

    • โœ… ์‹ค๋ฌด ์ƒํ™ฉ์„ CTE๋กœ ๋ชจ๋ธ๋ง
    • โœ… ๊ฐ€๋…์„ฑ๊ณผ ์„ฑ๋Šฅ์˜ ๊ท ํ˜•์  ์ฐพ๊ธฐ
    • โœ… ํŒ€์›๋“ค์ด ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ ์ž‘์„ฑ

    ํ•ต์‹ฌ ์š”์•ฝ: CTE๋Š” ๋ณต์žกํ•œ SQL์„ ๋‹จ๊ณ„๋ณ„๋กœ ๋‚˜๋ˆ ์„œ ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๋ถ„์„์—์„œ๋Š” ํ•„์ˆ˜ ์Šคํ‚ฌ์ด์—์š”! ๐Ÿš€

    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€

Designed by Tistory.