2011-09-04 23 views
8

Nell'esempio seguente, perché viene restituita la query min(), ma la query max() non lo è?Problema della funzione di aggregazione 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

La query è ovviamente non valida in tutti gli altri RDBMS. Cosa ti aspetti che ritorni? –

risposta

7

La clausola HAVING viene utilizzato per filtrare gruppi di righe. Si fa riferimento a min(a) e max(a) che (in assenza di qualsiasi clausola GROUP BY) si aggregano su tutti i valori a nella tabella ma utilizzano un confronto con un singolo valore a.

Quindi, quale valore di a è previsto che MySQL utilizzi? Tutti gli altri RDBMS che conosco lanciano un errore a questo punto, ma MySQL lo consente. From the docs

standard SQL non consente la clausola HAVING per citarne qualsiasi colonna non trovato nella clausola GROUP BY meno che non sia racchiuso in una funzione di aggregazione . MySQL consente l'uso di tali colonne per semplificare i calcoli di . Questa estensione presuppone che le colonne non raggruppate corrispondano allo con gli stessi valori di gruppo. In caso contrario, il risultato è indeterminato.

Quindi nel tuo caso dai risultati che si stanno ottenendo sembra che essa ha finito per usare 1 come valore scalare per a, ma questo comportamento non è garantito e potrebbe altrettanto bene hanno utilizzato 2 o qualunque altra esistente a valore.

+0

E per dimostrare l'indeterminatezza dei risultati, è possibile aggiungere una riga che ha 'a = 0'. Ora entrambe le tue dichiarazioni non restituiranno righe. – NullUserException

+2

Il modo corretto per fare ciò è usare una subquery: 'select * from t where a = (seleziona min (a) da t);' – NullUserException

Problemi correlati