Cómo usar group by con union en t-sql
-
05-07-2019 - |
Pregunta
¿Cómo puedo usar group by con union en t-sql? Quiero agrupar por la primera columna de un resultado de unión, escribí el siguiente sql pero no funciona. Simplemente no sé cómo hacer referencia a la columna especificada (en este caso es 1) del resultado de la unión. muchas gracias.
SELECT *
FROM ( SELECT a.id ,
a.time
FROM dbo.a
UNION
SELECT b.id ,
b.time
FROM dbo.b
)
GROUP BY 1
Solución
GRUPO POR 1
Nunca he sabido de GROUP BY para admitir el uso de ordinales, solo ORDER BY. De cualquier manera, solo MySQL admite GROUP BY que no incluye todas las columnas sin funciones agregadas realizadas en ellas. Los ordinales tampoco son prácticas recomendadas porque si se basan en el orden de SELECT, si eso cambia, también lo hace su ORDER BY (o GROUP BY si es compatible).
No es necesario ejecutar GROUP BY
en el contenido cuando utiliza UNION
: UNION garantiza que se eliminen los duplicados. UNION ALL
es más rápido porque no lo hace, y en ese caso necesitaría GROUP BY ...
Su consulta solo debe ser:
SELECT a.id,
a.time
FROM dbo.TABLE_A a
UNION
SELECT b.id,
b.time
FROM dbo.TABLE_B b
Otros consejos
Necesitas alias la subconsulta. Por lo tanto, su declaración debe ser:
Select Z.id
From (
Select id, time
From dbo.tablea
Union All
Select id, time
From dbo.tableb
) As Z
Group By Z.id
Identificar la columna es fácil:
SELECT *
FROM ( SELECT id,
time
FROM dbo.a
UNION
SELECT id,
time
FROM dbo.b
)
GROUP BY id
Pero no resuelve el problema principal de esta consulta: ¿qué se debe hacer con los valores de la segunda columna al agruparse por la primera? Ya que (¡peculiarmente!) Está utilizando UNION
en lugar de UNION ALL
, no tendrá duplicado por completo filas entre las dos subtablas en el unión, pero es posible que aún tengas varios valores de tiempo para un valor de id, y no das ninguna pista de lo que quieres hacer: ¿min, max, avg, suma o qué? El motor SQL debería dar un error debido a eso (aunque algunos como mysql simplemente seleccionan un valor aleatorio entre varios, creo que el servidor SQL es mejor que eso).
Entonces, por ejemplo, cambie la primera línea a SELECT id, MAX (time)
o similar.
with UnionTable as
(
SELECT a.id, a.time FROM dbo.a
UNION
SELECT b.id, b.time FROM dbo.b
) SELECT id FROM UnionTable GROUP BY id