SQL Subquery

子查詢 (SQL Subquery)

我們可以將一個 SQL 查詢語句塞入另一個 SQL 查詢語句中,這就是子查詢 (subquery)。子查詢是一個查詢內的查詢,我們可以用來連接資料表,或在不能使用單一語句來完成的查詢時我們就需要用到子查詢。

子查詢語法 (SQL Subquery Syntax)

SELECT column_name(s)
FROM table_name
WHERE column_name operator
(SELECT column_name FROM table_name WHERE condition);

子查詢用法 (Example)

假設我們有一個員工資料表 employees:

NameDepartmentSalary
張一業務部35000
王二資訊部42000
李三業務部38000
趙四資訊部45000

查詢薪水高於平均薪水的員工:

SELECT Name, Salary
FROM employees
WHERE Salary > (SELECT AVG(Salary) FROM employees);

查詢結果如下:

NameSalary
王二42000
趙四45000

使用 CTE 改寫子查詢 (Common Table Expression)

除了子查詢之外,SQL 還提供了 CTE(Common Table Expression,通用表示式)作為替代寫法。CTE 使用 WITH 關鍵字來定義一個暫時的命名結果集,讓查詢變得更易讀、更好維護。當子查詢變得複雜或需要重複使用時,CTE 是更好的選擇。

CTE 語法 (CTE Syntax)

WITH cte_name AS (
    SELECT column_name(s)
    FROM table_name
    WHERE condition
)
SELECT column_name(s)
FROM cte_name;

WITH 關鍵字用來定義 CTE,cte_name 是我們給這個暫時結果集的名稱,括號內的查詢就是 CTE 的定義。定義完成後,我們就可以在主查詢中像使用資料表一樣來使用 CTE。

CTE 用法範例 (CTE Example)

我們可以用 CTE 來改寫前面的子查詢範例,查詢薪水高於平均薪水的員工:

WITH avg_salary AS (
    SELECT AVG(Salary) AS AvgSalary
    FROM employees
)
SELECT Name, Salary
FROM employees, avg_salary
WHERE Salary > avg_salary.AvgSalary;

這個查詢與子查詢的結果完全相同,但 CTE 的寫法讓查詢的邏輯更清晰:先計算平均薪水,再用這個結果來篩選員工。

多個 CTE 的使用 (Multiple CTEs)

CTE 還有一個強大的優點,就是可以在同一個查詢中定義多個 CTE,用逗號分隔:

WITH dept_avg AS (
    SELECT Department, AVG(Salary) AS AvgSalary
    FROM employees
    GROUP BY Department
),
overall_avg AS (
    SELECT AVG(Salary) AS OverallAvg
    FROM employees
)
SELECT d.Department, d.AvgSalary, o.OverallAvg
FROM dept_avg d, overall_avg o;

這個範例同時計算了各部門的平均薪水和全體平均薪水,如果用子查詢寫會變得難以閱讀,但用 CTE 就能清楰地分步驟處理。

子查詢與 CTE 的比較

比較項目子查詢 (Subquery)CTE (WITH)
可讀性巢狀結構,複雜時較難閱讀分步定義,邏輯清晰
重複使用需要重複寫同一段查詢定義一次即可多次引用
遞迴查詢不支援支援遞迴 CTE
適用場景簡單的單次查詢複雜的多步驟查詢

延伸閱讀

留言功能已關閉。