2009-02-19 14 views
21

Mam dwie kwerendy SQL, gdzie pierwszy z nich jest:Dołącz dwóch zapytań 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; 

a druga to: '?'

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; 

(umysł Dont the, one oznaczają parametr w birt). Co chcę osiągnąć, to: Chcę, aby zapytanie SQL zwracało to samo, co pierwsze zapytanie, ale z dodatkową (trzecią) kolumną, która wygląda dokładnie tak, jak "Total Amount 2008" (od drugiego zapytania).

+2

Rejestracja to termin niejasny. Masz na myśli "łączenie zewnętrzne" lub "łączenie wewnętrzne"? Co dzieje się z działaniami, które nie są zgodne między tymi dwoma zapytaniami? –

Odpowiedz

38

Niektóre DBMS obsługuje składni FROM (SELECT ...) AS alias_name.

Pomyśl o swoich dwóch oryginalnych zapytaniach jako tabelach tymczasowych. można wyszukać je tak:

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

Problem polega jednak na tym, że jeśli jedno działanie ma wartość zero, to działanie nie zostanie wyświetlone. ewentualnie naprawić to za pomocą tego eleganckiego rozwiązania? – Schildmeijer

+0

jeśli działanie było (zerowe) zamiast 0, byłby to kawałek ciasta z lewym złączem zewnętrznym. Ale w tym przypadku jest to raczej trudne, obawiam się ... – Natrium

+0

Być może mógłbyś połączyć to zapytanie ze specjalnym przypadkiem dla zera po lewej i jednego dla zera po prawej. – Liam

1

Spróbuj tego:

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; 

Zasadniczo musisz dołączyć tabelę Incomes2008 z wyjściem pierwszego zapytania.

+0

Ponieważ korzystałeś z połączeń wewnętrznych, wynik nie będzie zawierał wierszy bez dochodów w 2008 r. Ani nie uzyskał dochodu w 2009 r. (Tzn. Nie ma wiersza w tabeli dochodów) –

+0

Zgadnij, że śpieszyłem się, aby opublikować ... Pracuj teraz ... –

+0

Moja pierwsza próba wyglądała mniej więcej tak. didnt work that – 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

Instrukcja kompiluje, ale obliczone sumy są zbyt duże. – Schildmeijer

+0

Niestety, nie otrzymałem tego, co chcesz za pierwszym razem. Zobacz zaktualizowany post. – Quassnoi

9

Chciałbym po prostu użyć Union

W swoim drugim zapytaniu dodać dodatkową nazwę kolumny i dodać '' we wszystkich odpowiednich miejscach w innych zapytań

Przykład

//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

Jeśli przyjmiesz, że wartości istnieją dla wszystkich działań w obu latach, po prostu wykonaj wewnętrzne sprzężenie w następujący sposób:

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 

Jeśli nie można zakładać, to wtedy patrzeć robi sprzężenie zewnętrzne

+0

Przepraszamy, że mógł być dodatkowy średnik. –

1

być może nie jest najbardziej elegancki sposób na rozwiązanie tego

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

Oto co pracował dla mnie:

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 

użyłem łączy, a nie związki (ja potrzebowałem różnych kolumn dla każdego zapytania, sprzężenie stawia to wszystko w ten sam kolumna) i porzuciłem znaki cudzysłowu (w porównaniu do tego, co robił Liam), ponieważ dawały mi błędy.

Dzięki! Nie mogłem tego oderwać bez tej strony! PS: Przepraszam, nie wiem, jak wyciągasz wyciągi sformatowane kolorami. itp.

-1

Możesz użyć CTE również jak poniżej.

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