2009-02-19 21 views
21

que tienen dos consultas SQL, donde el primero es:unir dos consultas SQL

select Activity, SUM(Amount) as "Total Amount 2009" 
from Activities, Incomes 
where Activities.UnitName = ? AND 
     Incomes.ActivityId = Activities.ActivityID 
GROUP BY Activity 
ORDER BY Activity; 

y el segundo es: '?'

select Activity, SUM(Amount) as "Total Amount 2008" 
from Activities, Incomes2008 
where Activities.UnitName = ? AND 
     Incomes2008.ActivityId = Activities.ActivityID 
GROUP BY Activity 
ORDER BY Activity; 

(no me importa la, que representan una parámetro en birt). Lo que quiero lograr es lo siguiente: Quiero una consulta SQL que devuelva lo mismo que la primera consulta, pero con una columna adicional (tercera) que se ve exactamente como "Importe total 2008" (desde la segunda consulta).

+2

Unir es un término vago. ¿Te refieres a "unión externa" o "unión interna"? ¿Qué sucede con las actividades que no coinciden entre las dos consultas? –

Respuesta

38

Algunos DBMS soportan la sintaxis FROM (SELECT ...) AS alias_name.

Piense en sus dos consultas originales como tablas temporales. Se pueden realizar consultas ellos de esta manera:

SELECT t1.Activity, t1."Total Amount 2009", t2."Total Amount 2008" 
FROM (query1) as t1, (query2) as t2 
WHERE t1.Activity = t2.Activity 
+0

, sin embargo, el problema es que si una actividad es cero, esa actividad no se mostrará. Posible arreglar eso con esta elegante solución? – Schildmeijer

+0

si la actividad fuera (nula) en lugar de 0, sería un pedazo de pastel con una combinación externa izquierda. Pero en este caso es bastante difícil, temo ... – Natrium

+0

Tal vez podrías unir esta consulta con un caso especial para un cero a la izquierda y uno para un cero a la derecha. – Liam

1

Prueba esto:

select Activity, SUM(Incomes.Amount) as "Total Amount 2009", SUM(Incomes2008.Amount) 
as "Total Amount 2008" from 
Activities, Incomes, Incomes2008 
where Activities.UnitName = ? AND 
Incomes.ActivityId = Activities.ActivityID AND 
Incomes2008.ActivityId = Activities.ActivityID GROUP BY 
Activity ORDER BY Activity; 

Básicamente, usted tiene que unirse a la mesa Incomes2008 con la salida de su primera consulta.

+0

Como ha utilizado combinaciones internas, el resultado no contendrá filas sin ingresos en 2008 ni ingresos en 2009 (es decir, no tendrá una fila en la tabla de ingresos) –

+0

Supongo que tenía prisa por publicar ... Shd trabajo ahora ... –

+0

Mi primer intento se parecía a esto. no funcionó aunque – Schildmeijer

15
SELECT Activity, arat.Amount "Total Amount 2008", abull.Amount AS "Total Amount 2009" 
FROM 
    Activities a 
LEFT OUTER JOIN 
    (
    SELECT ActivityId, SUM(Amount) AS Amount 
    FROM Incomes ibull 
    GROUP BY 
    ibull.ActivityId 
) abull 
ON abull.ActivityId = a.ActivityID 
LEFT OUTER JOIN 
    (
    SELECT ActivityId, SUM(Amount) AS Amount 
    FROM Incomes2008 irat 
    GROUP BY 
    irat.ActivityId 
) arat 
ON arat.ActivityId = a.ActivityID 
WHERE a.UnitName = ? 
ORDER BY Activity 
+0

La declaración se compila, pero las sumas calculadas son demasiado grandes – Schildmeijer

+0

Lo siento, no obtuve lo que desea la primera vez. Ver publicación actualizada. – Quassnoi

9

me acaba de utilizar un Union

En su segunda consulta añadir el nombre de la columna extra y añadir un '' en todos los lugares correspondientes en las otras consultas

Ejemplo

//reverse order to get the column names 
select top 10 personId, '' from Telephone//No Column name assigned 
Union 
select top 10 personId, loanId from loan 
1

Si supone que existen valores para todas las actividades en ambos años, simplemente realice una unión interna de la siguiente manera

select act.activity, t1.amount as "Total 2009", t2.amount as "Total 2008" 
from Activities as act, 
    (select activityid, SUM(Amount) as amount 
    from Activities, Incomes 
    where Activities.UnitName = ? AND 
      Incomes.ActivityId = Activities.ActivityID 
    GROUP BY Activityid) as t1, 
    (select activityid, SUM(Amount) as amount 
    from Activities, Incomes2008 
    where Activities.UnitName = ? AND 
      Incomes2008.ActivityId = Activities.ActivityID 
    GROUP BY Activityid) as t2 
    WHERE t1.activityid= t2.activityid 
    AND act.activityId = t1.activityId 
    ORDER BY act.activity 

Si usted no puede asumir esto, a continuación, busque en hacer una combinación externa

+0

Lo sentimos, puede haber sido un punto y coma adicional corriendo. –

1

tal vez no sea la forma más elegante de resolver este

select Activity, 
     SUM(Amount) as "Total_Amount", 
     2009 AS INCOME_YEAR 
from Activities, Incomes 
where Activities.UnitName = ? AND 
     Incomes.ActivityId = Activities.ActivityID 
GROUP BY Activity 
ORDER BY Activity; 

UNION 

select Activity, 
     SUM(Amount) as "Total_Amount", 
     2008 AS INCOME_YEAR 
from Activities, Incomes2008 
where Activities.UnitName = ? AND 
     Incomes2008.ActivityId = Activities.ActivityID 
GROUP BY Activity 
ORDER BY Activity; 
2

Esto es lo que funcionó para mí:

select visits, activations, simulations, simulations/activations 
    as sims_per_visit, activations/visits*100 
    as adoption_rate, simulations/activations*100 
    as completion_rate, duration/60 
    as minutes, m1 as month, Wk1 as week, Yr1 as year 

from 
(
    (select count(*) as visits, year(stamp) as Yr1, week(stamp) as Wk1, month(stamp) 
    as m1 from sessions group by week(stamp), year(stamp)) as t3 

    join 

    (select count(*) as activations, year(stamp) as Yr2, week(stamp) as Wk2, 
    month(stamp) as m2 from sessions where activated='1' group by week(stamp), 
    year(stamp)) as t4 

    join 

    (select count(*) as simulations, year(stamp) as Yr3 , week(stamp) as Wk3, 
    month(stamp) as m3 from sessions where simulations>'0' group by week(stamp), 
    year(stamp)) as t5 

    join 

    (select avg(duration) as duration, year(stamp) as Yr4 , week(stamp) as Wk4, 
    month(stamp) as m4 from sessions where activated='1' group by week(stamp), 
    year(stamp)) as t6 
) 
where Yr1=Yr2 and Wk1=Wk2 and Wk1=Wk3 and Yr1=Yr3 and Yr1=Yr4 and Wk1=Wk4 

Solía ​​une, no sindicatos (I necesitan diferentes columnas para cada consulta, una unión lo pone todo en la misma columna) y dejé las comillas (en comparación con lo que Liam estaba haciendo) porque me estaban dando errores.

Gracias! ¡No podría haberlo logrado sin esta página! PD: Lo siento, no sé cómo va a obtener sus estados de cuenta formateados con colores. etc.

-1

Puede usar CTE también como a continuación.

With cte as 
(select Activity, SUM(Amount) as "Total Amount 2009" 
    from Activities, Incomes 
    where Activities.UnitName = ? AND 
     Incomes.ActivityId = Activities.ActivityID 
    GROUP BY Activity 
), 
cte1 as 
(select Activity, SUM(Amount) as "Total Amount 2008" 
    from Activities, Incomes2008 
    where Activities.UnitName = ? AND 
     Incomes2008.ActivityId = Activities.ActivityID 
    GROUP BY Activity 
) 
Select cte.Activity, cte.[Total Amount 2009] ,cte1.[Total Amount 2008]  
    from cte join cte1 ON cte.ActivityId = cte1.ActivityID 
WHERE a.UnitName = ? 
ORDER BY cte.Activity