2011-09-04 111 views
8

在以下示例中,爲什麼min()查詢返回結果,但max()查詢不?MySQL聚合函數問題

mysql> create table t(id int, a int); 
Query OK, 0 rows affected (0.10 sec) 

mysql> insert into t(id, a) values(1, 1); 
Query OK, 1 row affected (0.03 sec) 

mysql> insert into t(id, a) values(1, 2); 
Query OK, 1 row affected (0.02 sec) 

mysql> select * from t 
    -> ; 
+------+------+ 
| id | a | 
+------+------+ 
| 1 | 1 | 
| 1 | 2 | 
+------+------+ 
2 rows in set (0.00 sec) 

mysql> select * from t where a < 4; 
+------+------+ 
| id | a | 
+------+------+ 
| 1 | 1 | 
| 1 | 2 | 
+------+------+ 
2 rows in set (0.00 sec) 

mysql> select * from t where a < 4 having a = max(a); 
Empty set (0.00 sec) 

mysql> select * from t where a < 4 having a = min(a); 
+------+------+ 
| id | a | 
+------+------+ 
| 1 | 1 | 
+------+------+ 
1 row in set (0.00 sec) 
+2

該查詢在所有其他RDBMS中當然無效。你期望它返回什麼? –

回答

7

HAVING子句用於過濾行的組。您參考min(a)max(a)哪些(在沒有任何GROUP BY條款的情況下)在表中的所有a值上聚合,但是隨後使用與單個a值的比較。

那麼MySQL應該使用哪個值a?我知道的所有其他RDBMS在這一點上都會引發錯誤,但是MySQL確實允許這樣做。 From the docs

標準SQL不允許HAVING子句來命名GROUP BY子句中沒有發現,除非它被封裝在一個聚合 功能的任何列 。 MySQL允許使用這樣的列來簡化 的計算。此擴展假設非分組列將 具有相同的分組值。 否則,結果是 不確定。

所以你的情況從你所得到的結果看來,它結束了使用1a標值,但這種行爲並不能完全保證其可以等效地使用2或任何其他現有a值。

+0

爲了證明結果的不確定性,可以添加一個'a = 0'的行。現在你的語句都不會返回任何行。 – NullUserException

+2

正確的做法是使用子查詢:'select * from t where a =(select min(a)from t);' – NullUserException