2011-09-04 8 views
8

En el siguiente ejemplo, ¿por qué la consulta min() devuelve resultados, pero la consulta max() no?Problema de la función de agregado 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 consulta es, por supuesto, inválida en todos los demás RDBMS. ¿Qué esperas que vuelva? –

Respuesta

7

La cláusula HAVING se utiliza para filtrar grupos de filas. Hace referencia a min(a) y max(a) que (en ausencia de cualquier cláusula GROUP BY) se agregan sobre todos los valores a de la tabla pero luego usan una comparación con un valor único de a.

¿Qué valor de a se supone que usa MySQL? Todos los otros RDBMS que conozco arrojarían un error en este punto, sin embargo, MySQL lo permite. From the docs

estándar SQL no permite la cláusula HAVING para nombrar cualquier columna no se encuentra en la cláusula GROUP BY a no ser que se encierra en una función de agregado . MySQL permite el uso de tales columnas para simplificar los cálculos de . Esta extensión supone que las columnas no agrupadas tendrán con los mismos valores para grupos. De lo contrario, el resultado es indeterminado.

Así que en su caso de los resultados que está obteniendo parece que terminó usando 1 como el valor escalar para a pero este comportamiento no está garantizada y podría igualmente bien han utilizado 2 o cualquier otro a existente valor.

+0

Y para demostrar la indeterminación de los resultados, puede agregar una fila que tenga 'a = 0'. Ahora sus dos declaraciones no devolverán filas. – NullUserException

+2

La forma correcta de hacer esto es usar una subconsulta: 'select * from t donde a = (seleccione min (a) de t);' – NullUserException

Cuestiones relacionadas