首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

面試必考:MySQL GROUP BY 深度解析與實戰技巧

     編輯:MySQL 綜合教學

MySQL GROUP BY 面試全解析:從基礎分組到 HAVING 進階

GROUP BY 是面試高頻考點,考察對分組聚合、非聚合列選擇、HAVING vs WHERE、ONLY_FULL_GROUP_BY 模式的理解。

基礎數據準備

CREATE TABLE student (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(30), sex TINYINT, score INT, dept VARCHAR(10)
);
INSERT INTO student VALUES
(1,'a',1,90,'dev'),(2,'b',1,90,'dev'),(3,'b',0,88,'design'),
(4,'c',0,60,'sales'),(5,'c',0,89,'sales'),(6,'d',1,100,'product');

1. 基礎分組聚合

SELECT dept, MAX(score) AS max_score
FROM student GROUP BY dept;

結果:每部門最高分。注意:未分組列(name, sex, score)在 SELECT 中出現時,MySQL 非 ONLY_FULL_GROUP_BY 模式下任意取值,嚴格模式下報錯。

2. HAVING 過濾分組

-- 部門總分 > 150 的最高分
SELECT dept, MAX(score) FROM student
GROUP BY dept HAVING SUM(score) > 150;

-- 僅男生(sex=1)參與分組的最高分
SELECT dept, MAX(score) FROM student
WHERE sex = 1 GROUP BY dept;
-- 或
SELECT dept, MAX(score) FROM student
GROUP BY dept HAVING sex = 1;  -- 非標準,依賴 ONLY_FULL_GROUP_BY=OFF

核心區別:WHERE 在分組前過濾行;HAVING 在分組後過濾組,可用聚合函數。

3. 去重與非聚合列選擇

-- 僅獲取不重複部門
SELECT DISTINCT dept FROM student;

-- 獲取部門及任一學生名(非標準)
SELECT dept, name FROM student GROUP BY dept;

嚴格模式(ONLY_FULL_GROUP_BY,5.7+ 默認開啟)要求 SELECT 列必須出現在 GROUP BY 或聚合函數中。解決方案:

  • 加入聚合:MAX(name)、ANY_VALUE(name)(5.7+)。
  • 子查詢先聚合再 JOIN 回表取明細。

4. 進階:分組內 Top-N

每部門最高分的學生信息(MySQL 8.0 窗口函數):

SELECT * FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY dept ORDER BY score DESC) AS rn
  FROM student
) t WHERE rn = 1;

5.7 兼容寫法(變量模擬行號或自連接)。

5. 常見面試陷阱

陷阱錯誤寫法正確寫法
非聚合列任意值SELECT dept, name FROM t GROUP BY deptSELECT dept, ANY_VALUE(name) FROM t GROUP BY dept
WHERE 用聚合函數SELECT dept FROM t WHERE COUNT(*) > 5 GROUP BY deptSELECT dept FROM t GROUP BY dept HAVING COUNT(*) > 5
HAVING 無 GROUP BYSELECT * FROM t HAVING score > 90SELECT * FROM t WHERE score > 90
分組字段與 SELECT 不一致SELECT dept, MAX(score) FROM t GROUP BY nameSELECT dept, MAX(score) FROM t GROUP BY dept

6. ONLY_FULL_GROUP_BY 影響

-- 查看當前模式
SELECT @@sql_mode;
-- 臨時關閉(不推薦生產)
SET SESSION sql_mode = REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', '');

建議代碼兼容嚴格模式,避免升級後報錯。

總結

面試核心考點:WHERE vs HAVING 執行順序、非聚合列處理、ONLY_FULL_GROUP_BY 語義、分組 Top-N 寫法。熟練掌握上述場景,GROUP BY 題目穩拿高分。

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