表 t2(id PK, a),數據:(1,10)、(3,1)。
SELECT * FROM t2 HAVING id = MIN(id); -- 返回 id=1 SELECT * FROM t2 HAVING id = MAX(id); -- 空結果!
同理 HAVING a = MAX(a) 返回 a=10,HAVING a = MIN(a) 卻空結果。為什麼?
GROUP BY NULL標準 SQL 要求 HAVING 伴隨 GROUP BY。MySQL 為兼容單獨 HAVING,隱式重寫:
SELECT * FROM t2 HAVING id = MIN(id) -- 內部等價於 SELECT * FROM t2 GROUP BY NULL HAVING id = MIN(id);
GROUP BY NULL 的行為 = LIMIT 1SELECT * FROM t2 GROUP BY NULL; -- 只返回第一行 (1,10)
分組後**僅保留第一行**作為唯一分組。
關鍵點:**MIN/MAX 計算的是全表所有行的極值,而非分組內(此處分組內僅有一行)。**
SELECT MAX(a), MIN(a), MAX(id), MIN(id) FROM t2 GROUP BY NULL; +--------+--------+---------+---------+ | MAX(a) | MIN(a) | MAX(id) | MIN(id) | +--------+--------+---------+---------+ | 10 | 1 | 3 | 1 | +--------+--------+---------+---------+
HAVING id = MIN(id) → HAVING id = 1 → 分組內第一行 id=1 滿足 → **返回該行**。HAVING id = MAX(id) → HAVING id = 3 → 分組內第一行 id=1 不滿足 → **空結果**。HAVING a = MAX(a) → HAVING a = 10 → 分組內第一行 a=10 滿足 → **返回**。HAVING a = MIN(a) → HAVING a = 1 → 分組內第一行 a=10 不滿足 → **空結果**。-- 取最小 id 的完整行 SELECT * FROM t2 ORDER BY id ASC LIMIT 1; -- 取最大 a 的完整行 SELECT * FROM t2 ORDER BY a DESC LIMIT 1;
sql_mode=ONLY_FULL_GROUP_BY,MySQL 5.7.5+ 預設開啟,會直接報錯攔截此類寫法。