Encontré este rompecabezas en los comentarios aquí
CREATE TABLE r (b INT);
SELECT 1 FROM r HAVING 1=1;
SQL Server y PostgreSQL devuelven 1 fila.
MySQL y Oracle devuelven cero filas.
¿Cual es correcta? ¿O son ambos igualmente válidos?
aggregate
sql-standard
Martin Smith
fuente
fuente
SELECT COUNT(*) FROM r;
devuelve 1 fila (con0
), mientras queSELECT COUNT(*) FROM r GROUP BY ();
no devuelve ninguna fila.SELECT 1 WHERE 1=0 HAVING 1=1;
. SQL Server y PostgreSQL aún devuelven una fila. Oracle quiere DE DUAL y no devuelve filas. MySQL no compila ni con FROM DUAL ni sin él .SELECT 1 AS t FROM (SELECT 1) tmp WHERE 1=0 HAVING 1=1;
1-row-no-dual y devuelve 0 filas.<group by clause>
, entonces“GROUP BY ()”
está implícito". ¿No deberían ambas consultas devolver los mismos resultados entonces?HAVING
diferente): SQl-fiddle 2: HAVING hace las cosas diferentesRespuestas:
Por el estándar:
medio
Cita ISO / IEC 9075-2: 2011 7.10 Regla de sintaxis 1 (Parte de la definición de la cláusula HAVING):
Ok, eso está bastante claro.
Afirmación:
1=1
es verdadera condición de búsqueda. No proporcionaré ninguna cita para esto.Ahora
es equivalente a
Cita ISO / IEC 9075-2: 2011 7.10 Regla general 1:
Lógica: dado que la condición de búsqueda siempre es verdadera, el resultado es
R
, que es el resultado del grupo por expresión.Lo siguiente es un extracto de las Reglas Generales de 7.9 (la definición del GRUPO POR CLÁUSULA)
Así podemos concluir que
da como resultado una tabla agrupada, que consta de un grupo, con cero filas (ya que R está vacío).
Un extracto de las Reglas generales de 7.12, que define una Especificación de consulta (también conocida como una instrucción SELECT):
Por lo tanto, dado que la tabla tiene un grupo, debe tener una fila de resultados.
Así
debería devolver un conjunto de resultados de 1 fila.
QED
fuente
Cuando hay una
HAVING
cláusula, sin unaWHERE
cláusula:... entonces
GROUP BY ()
está implícito. Entonces, la consulta debe ser equivalente a:... que debería agrupar todas las filas de la tabla en un grupo (incluso si la tabla no tiene filas en absoluto, sigue siendo un grupo de 0 filas) y devolver 1 fila. El
HAVING
con laTrue
condición no debería tener ningún efecto después de eso.Desde un ángulo diferente, ¿cuántas filas debería devolver una consulta como esta?
¿Uno, cero o "cero o uno, dependiendo de si la tabla está vacía o no"?
Creo que una fila, no importa cuántas filas
r
tenga.fuente
Por lo que veo, parece que SQLServer y PostgerSQL no se molestan en mirar la tabla en absoluto:
También devuelve solo una fila. Aunque los documentos de SQLServer dicen
eso no es cierto en este caso, en
WHERE 1=1
lugar deHAVING
devolver el número adecuado de filas. Yo diría que es un error del optimizador (o al menos un error de documentación) ... el plan SQLServer muestra 'Análisis constante' en caso deHAVING
'análisis de tabla' paraWHERE
...El comportamiento de Oracle y Mysql me parece más lógico y correcto ...
fuente
explain
"Resultado (filas = 1) ..." para tener y "Seq Scan" para "DONDE" tampoco se ve en la tabla. .. Supongo que de alguna manera está relacionado con el hecho de que "FROM" no es obligatorio en TSQL y PostgreSQL. Sé que Mysql tampoco lo requiere, pero dado que son compatiblesdual
, probablemente analicen la consulta un poco diferente. Estoy de acuerdo, parece una especulación, pero espero que tenga sentido.