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

SQL GROUP BY 查詢中非聚合列報錯的原因與正確寫法

     編輯:程式設計綜合問答

錯誤 SQL

SELECT deptno, ename
FROM emp
GROUP BY deptno

報錯原因

SQL 標準規定:`SELECT` 列表中的每一列,必須滿足以下任一條件:

  1. 出現在 `GROUP BY` 子句中 (分組列)。
  2. 包含在聚合函數中 (`COUNT`, `SUM`, `AVG`, `MAX`, `MIN`, `GROUP_CONCAT` 等)。

錯誤 SQL 中 `ename` 既不在 `GROUP BY`,也無聚合函數。分組後每組包含多行,每行 `ename` 可能不同 (如 10 部門有 CLARK, KING, MILLER),數據庫**無法決定選哪一個** 代表該組,因此拒絕執行。

正確寫法 (視業務需求)

1. 只查分組列 + 聚合信息 (最標準)

SELECT deptno, COUNT(*) AS emp_count, AVG(sal) AS avg_sal
FROM emp
GROUP BY deptno

2. 需顯示每組某行的 ename (如工資最高者)

使用窗口函數 (MySQL 8.0+, PostgreSQL, Oracle, SQL Server):

SELECT deptno, ename, sal
FROM (
    SELECT deptno, ename, sal,
           ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY sal DESC) AS rn
    FROM emp
) t
WHERE rn = 1

3. 需將每組所有 ename 拼成字符串

-- MySQL
SELECT deptno, GROUP_CONCAT(ename ORDER BY ename) AS enames
FROM emp
GROUP BY deptno

-- PostgreSQL
SELECT deptno, STRING_AGG(ename, ',' ORDER BY ename) AS enames
FROM emp
GROUP BY deptno

-- SQL Server (2017+)
SELECT deptno, STRING_AGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS enames
FROM emp
GROUP BY deptno

-- Oracle
SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS enames
FROM emp
GROUP BY deptno

4. MySQL 舊版本 (ONLY_FULL_GROUP_BY 關閉) 允許的非標準寫法

SELECT deptno, ename -- 任意取組內一行的 ename (不可預測哪一行)
FROM emp
GROUP BY deptno

**強烈不推薦**:結果不確定,遷移數據庫版本或開啟 `ONLY_FULL_GROUP_BY` 即報錯。

核心原則

「分組後每組是很多記錄,沒有分組的字段的值可能不同,你選擇字段,你選擇的是哪個呢?」

始終明確:`GROUP BY` 產生的是**組級別**的摘要行,`SELECT` 必須表達「組的屬性」。

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