Tag Archive Query

Byphunsanit

Database: Common Table Expressions (CTE)

Common Table Expressions (CTE) เป็นมาตราฐาน ANSI SQL:1999 แต่ SQL Server รองรับในเวอร์ชัน 2005 เริ่มใช้ได้กับ SELECT, INSERT, UPDATE, และ DELETE และคำสั่ง MERGE ตั้งแต่เวอร์ชัน SQL Server 2008 โดยได้นำมาใช้เพื่อช่วยให้การเขียน Query ที่ซับซ้อนอ่านง่ายขึ้นและรองรับการทำ Recursive Query (คิวรีแบบเรียกซ้ำ) แทนคิวรีที่มีความซับซ้อน มีการ Join กันหลายชั้น หรือต้องคำนวณซ้อนกันไปมา


CTE คืออะไร?

CTE คือ ผลลัพธ์ชั่วคราว (Temporary Result Set) ที่ถูกนิยามขึ้นมาเพื่อให้เราสามารถอ้างอิงถึงได้ภายในประโยคคำสั่ง SELECT, INSERT, UPDATE หรือ DELETE ตัวเดียว โดยมองว่ามันคือการสร้าง “ตารางเสมือน” ขึ้นมาใช้ชั่วคราวในขณะที่ Query กำลังทำงาน


โครงสร้างพื้นฐานของ CTE

เราจะเริ่มต้นด้วยคำสำคัญ WITH ตามด้วยชื่อของ CTE และนิยาม SQL ภายในวงเล็บ

WITH CTE_Name AS (
    -- SQL statement to define the CTE
    SELECT column1, column2
    FROM table_name
    WHERE condition
)
-- Query using the CTE
SELECT *
FROM CTE_Name;

ทำไมต้องใช้ CTE? (จุดเด่นที่สำคัญ)

  • Readability (อ่านง่าย): แทนที่จะเขียน Subquery ซ้อนกันใน FROM หรือ WHERE จนงง เราสามารถแยก logic ออกมาเป็นส่วนๆ ด้านบนได้
  • Reusability (ใช้ซ้ำได้): ภายใน Query เดียวกัน คุณสามารถเรียกใช้ CTE เดิมซ้ำได้หลายครั้ง (เช่น นำ CTE มา Self-join กันเอง)
  • Recursion (การเรียกตัวเอง): นี่คือไม้ตายของ CTE ที่ Subquery ธรรมดาทำไม่ได้ คือการเขียน Recursive CTE เพื่อจัดการกับข้อมูลที่มีโครงสร้างเป็นลำดับชั้น (Hierarchy) เช่น ผังองค์กร หรือโครงสร้างสินค้า

ประเภทของ CTE

  1. Non-Recursive CTE
    คือการใช้งานทั่วไปเพื่อจัดกลุ่มข้อมูลให้เป็นระเบียบ เช่น การหาค่าเฉลี่ยก่อนแล้วค่อยนำไป Filter
    WITH AverageSalary AS (
        SELECT DepartmentID, AVG(Salary) as AvgSal
        FROM Employees
        GROUP BY DepartmentID
    )
    SELECT e.Name, e.Salary, a.AvgSal
    FROM Employees e
    JOIN AverageSalary a ON e.DepartmentID = a.DepartmentID
    WHERE e.Salary > a.AvgSal;
    
  2. Recursive CTE
    ใช้สำหรับข้อมูลที่มีความสัมพันธ์เป็นทอดๆ เช่น การหาว่าพนักงานคนนี้อยู่ภายใต้สายการบังคับบัญชาของใครบ้าง โดยจะประกอบด้วยสองส่วนคือ Anchor member (จุดเริ่มต้น) และ Recursive member (ส่วนที่วนลูป) เชื่อมกันด้วย UNION ALL
    คุณสมบัติCTESubqueryTemp Table (#)
    ความอ่านง่ายสูงมากต่ำ (ถ้าซ้อนเยอะ)ปานกลาง
    ขอบเขตการใช้งานเฉพาะใน Query นั้นเฉพาะในวงเล็บนั้นตลอดทั้ง Session
    การใช้ซ้ำได้ (ใน Query เดียวกัน)ไม่ได้ได้ (จนกว่าจะลบ)
    Recursionรองรับไม่รองรับไม่รองรับ

สรุป

CTE เปรียบเสมือนการสร้างตัวแปรในโลกของ SQL ที่ช่วยให้เราจัดระเบียบความคิดและ Code ให้สะอาดขึ้น หากคุณต้องการเขียน Query ที่ซับซ้อนแต่ยังอยากให้เพื่อนร่วมงาน (หรือตัวคุณเองในอนาคต) อ่านรู้เรื่อง CTE คือทักษะที่คุณไม่ควรพลาดครับ


อ่านเพิ่มเติม