首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

SQL 改寫:子查詢轉 GROUP BY HAVING

     編輯:程式設計綜合問答

原始查詢

SELECT empfname, empsalary
FROM qemp
WHERE empsalary < (SELECT 0.90 * AVG(empsalary) FROM qemp);

改寫嘗試與錯誤分析

直接改寫為:

SELECT empfname, empsalary
FROM qemp
GROUP BY empsalary
HAVING empsalary > 90 * AVG(empsalary);

錯誤原因:

  • GROUP BY empsalary 會將相同薪資分組,但 empfname 未出現在 GROUP BY 且非聚合函數,違反 SQL 標準(MySQL ONLY_FULL_GROUP_BY 模式下報錯)。
  • HAVING 子句中 AVG(empsalary) 是組內平均,而非全表平均,語意不同。

正確改寫(保持原語意)

原查詢為「薪資低於全表平均 90% 的員工」,無需 GROUP BY,子查詢已是最佳寫法。若強制用 HAVING,需先計算全表平均:

SELECT empfname, empsalary
FROM qemp
CROSS JOIN (SELECT AVG(empsalary) * 0.9 AS threshold FROM qemp) t
WHERE empsalary < t.threshold;

何時使用 HAVING

  • 分組過濾:如「各部門平均薪資 > 5000 的部門」:GROUP BY dept HAVING AVG(sal) > 5000。
  • 原查詢無分組需求,子查詢更清晰且效能相當(優化器會轉為半連接)。

結論:並非所有子查詢都應改寫為 GROUP BY HAVING,應根據業務語意選擇最直觀、可維護的寫法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved