ÚNASE a dos resultados de la instrucción SELECT

174

¿Es posible unir los resultados de 2 SELECTdeclaraciones sql en una declaración? Tengo una base de datos de tareas donde cada registro es una tarea separada, con fechas límite (y una PALT, que es solo INTde días desde el inicio hasta la fecha límite. AgeTambién es un INTnúmero de días).

Quiero tener una tabla que tenga a cada persona en la tabla, la cantidad de tareas que tienen y la cantidad de LATEtareas que tienen (si corresponde).

Puedo obtener estos datos en tablas separadas fácilmente, así:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks

devolviendo datos como:

ks        # Tasks
person1   7
person2   3

y luego tengo:

SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks

que devuelve:

ks        # Late
person1   1
person2   1

Y quiero unir los resultados de estas dos selectdeclaraciones (por el KS)

Estoy tratando de evitar el uso de una tabla temporal, pero si esa es la única forma práctica de hacerlo, me gustaría saber más sobre el uso de tablas temporales de esta manera.

También intenté hacer algún tipo de count()filas que satisfagan un condicional, pero tampoco pude encontrar la manera de hacerlo. Si es posible, eso también funcionaría.

Adición: Lo siento, yo quiero que mis resultados tengan columnas de KS, TasksyLate

KS        # Tasks   # Late
person1   7         1
person2   3         1
person3   2         0  (or null)

Además, quiero que aparezca una persona incluso si no tienen tareas tardías.

SUM(CASE WHEN Age > Palt THEN 1 ELSE 0 END) Late
funciona bien, gracias por esta respuesta!

Dos sentencias select también funcionan, usar un LEFT JOINpara unirlas también funciona, y ahora entiendo cómo unir múltiples selects de esta manera

sylverfyre
fuente
No ha dado un ejemplo del resultado esperado. Por lo tanto, algunas respuestas son resultados concatenantes. Algunos se unen. ¿Cuál quieres?
Phil
Lo sentimos, quiero que mis resultados tengan columnas para KS, Tareas y KS tardío # Tareas # Tarde persona1 7 1 persona2 3 1 persona3 2 0 (o nulo) Además, quiero que aparezca una persona incluso si no tienen tareas tardías . Actualmente lograr esto usando los dos métodos de enunciado select con un JOIN IZQUIERDO (en oposición al INNER JOIN sugerido, que funciona pero no muestra personas sin tareas tardías porque no existen en el segundo SELECT. columna siendo SUMA (CASO CUANDO Edad> Palt ENTONCES 1 OTRO 0 FIN) Tarde
sylverfyre

Respuestas:

264
SELECT t1.ks, t1.[# Tasks], COALESCE(t2.[# Late], 0) AS [# Late]
FROM 
    (SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks) t1
LEFT JOIN
    (SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks) t2
ON (t1.ks = t2.ks);
Phil
fuente
1
Esto funciona bien, aunque no especifiqué que quiero una UNIÓN IZQUIERDA para que los registros aparezcan incluso si tienen 0 tareas tardías.
sylverfyre
Aceptado esta respuesta, ya que responde a la pregunta que más me pregunté, y está formateado para ser una gran referencia en unirse instrucciones SELECT :)
sylverfyre
Excelente respuesta, pero ¿alguien puede decir si este tipo de 'solución' se considera costosa o solo depende de para qué la esté usando?
petrosmm
71

Intenta algo como esto:

SELECT 
* 
FROM
(SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks) t1 
INNER JOIN
(SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks) t2
ON t1.ks = t2.ks
Mithrandir
fuente
44
No pude obtener la respuesta aceptada para trabajar, pero funcionó muy bien para mis necesidades. Gracias.
benvenker
Trabajado como un encanto. En lo que a mí respecta, esta debería ser la respuesta aceptada. Gracias.
nocdib
¡Trabajó para mi! ¡Gracias! También intenté usar múltiples consultas (múltiples combinaciones) y también funciona muy bien. Si alguien se pregunta, puede agregar más uniones después de la última "ENCENDIDO" en el ejemplo, y seguir usando la secuencia: ENCENDIDO ... X UNIRSE (CONSULTA N -1) ENCENDIDO Y = ZX UNIR (CONSULTA N) EN SÍ = Z
cesarmart
43

Uso UNION:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks
UNION
SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks

O UNION ALLsi quieres duplicados:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks
UNION ALL
SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks
aF.
fuente
3
Union o Union All tendrá solo 2 columnas en resultado. Donde como él quiere 3 de ellos
SurajS
14

Si Age y Palt son columnas en la misma tabla, puede contar (*) todas las tareas y sumar solo las últimas como esta:

select ks,
       count(*) tasks,
       sum(case when Age > Palt then 1 end) late
  from Table
 group by ks
Nikola Markovinović
fuente
1
Esto es EXACTAMENTE lo que quería, pero no sabía cómo buscarlo. No pensé en usar una SUMA (CASO), gracias.
sylverfyre