2011-09-04 14 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値との比較が使用されます。

だからa値はMySQLが使用されるはずですか?私が知っている他のすべてのRDBMSはこの時点でエラーを投げますが、MySQLはこれを許可します。 From the docs

標準SQLは、それが集計 機能で囲まれていない限りGROUP BY句では見られない任意の列 に名前を付けるためにHAVING句を許可していません。 MySQLでは、このような列を使用して の計算を簡素化することができます。この拡張は、グループ化されていない列が同じグループ単位の値を持つことを前提としています( )。 それ以外の場合、結果は 不確定です。

だから、あなたが得ている結果から、あなたの場合にはaのためのスカラー値として1を使用して終了と思われるが、この動作は保証されません、それは同様にうまく使うことができた2またはaを既存の任意の他の値。

+0

そして、結果の不確定性を証明するために、 'a = 0'を持つ行を追加することができます。両方のステートメントは行を返しません。 – NullUserException

+2

これを行う正しい方法は、サブクエリを使うことです: 'select * from t where a =(tからmin(a)を選択する);' – NullUserException