子查詢在 WHERE、HAVING 子句中的實戰應用模式,涵蓋比較測試、集合成員、存在性測試、量化比較,並對比 JOIN 改寫效能。
-- 銷售定額小於全公司目標 10% 的業務
SELECT NAME FROM SALESREPS
WHERE QUOTA < 0.1 * (SELECT SUM(TARGET) FROM OFFICES);
-- 目標超過該辦公室所有業務定額總和的辦公室
SELECT CITY FROM OFFICES
WHERE TARGET > (SELECT SUM(QUOTA) FROM SALESREPS WHERE REP_OFFICE = OFFICE);
-- 在西區辦公室任職的業務
SELECT NAME, AGE FROM SALESREPS
WHERE REP_OFFICE IN (SELECT OFFICE FROM OFFICES WHERE REGION = 'Western');
-- 有下過訂單的客戶
SELECT * FROM CUSTOMERS c
WHERE EXISTS (SELECT 1 FROM ORDERS o WHERE o.CUST_NUM = c.CUST_NUM);
-- 定額高於「至少一位」業務平均定額的人
SELECT NAME FROM SALESREPS
WHERE QUOTA > ANY (SELECT AVG(QUOTA) FROM SALESREPS GROUP BY REP_OFFICE);
-- 定額高於「所有」業務平均定額的人
SELECT NAME FROM SALESREPS
WHERE QUOTA > ALL (SELECT AVG(QUOTA) FROM SALESREPS GROUP BY REP_OFFICE);
-- 子查詢版
SELECT NAME, AGE FROM SALESREPS
WHERE REP_OFFICE IN (SELECT OFFICE FROM OFFICES WHERE REGION = 'Western');
-- JOIN 版 (通常效能較佳)
SELECT s.NAME, s.AGE FROM SALESREPS s
JOIN OFFICES o ON s.REP_OFFICE = o.OFFICE
WHERE o.REGION = 'Western';
原則:若子查詢為非相關且回傳集合,優先考慮 JOIN;若為匯總值 (如 AVG) 且外層非匯總,子查詢較直觀。
-- ACI 產品平均訂單大小 > 全公司平均訂單大小 的業務
SELECT NAME, AVG(AMOUNT) FROM SALESREPS, ORDERS
WHERE EMPL_NUM = REP AND MFR = 'ACI'
GROUP BY NAME
HAVING AVG(AMOUNT) > (SELECT AVG(AMOUNT) FROM ORDERS);
-- ACI 產品平均訂單 >= 該業務整體平均訂單 的業務
SELECT NAME, AVG(AMOUNT) FROM SALESREPS, ORDERS
WHERE EMPL_NUM = REP AND MFR = 'ACI'
GROUP BY NAME, EMPL_NUM
HAVING AVG(AMOUNT) >= (SELECT AVG(AMOUNT) FROM ORDERS WHERE REP = EMPL_NUM);
UNION 多個 SELECT。