2009-08-04 16 views
41

że mam dwie tabele:Łączenie dwóch tabel do jednego wyjścia

KnownHours:

 
ChargeNum CategoryID Month Hours 
111111  1    2/1/09 10 
111111  1    3/1/09 30 
111111  1    4/1/09 50 
222222  1    3/1/09 40 
111111  2    4/1/09 50 

UnknownHours:

 
ChargeNum Month Hours 
111111  2/1/09 70 
111111  3/1/09 40.5 
222222  7/1/09 25.5 

muszę grupy te godziny, ignorując miesiąc, w jeden tabela danych, aby mój oczekiwany wynik był następujący:

 
ChargeNum CategoryID  Hours 
111111  1    90 
111111  2    50 
111111  Unknown  110.5 
222222  1    40 
222222  Unknown  25.5 

Nie mogę tego zrozumieć. Każda pomoc będzie bardzo ceniona!

EDYCJA: Potrzebuję zsumować godziny dla każdej kombinacji ChargeNum/Category. Zaktualizowałem przykładowe dane, aby to odzwierciedlić.

Odpowiedz

65

Musisz użyć UNION, aby połączyć wyniki dwóch zapytań. W twoim przypadku:

SELECT ChargeNum, CategoryID, SUM(Hours) 
FROM KnownHours 
GROUP BY ChargeNum, CategoryID 
UNION ALL 
SELECT ChargeNum, 'Unknown' AS CategoryID, SUM(Hours) 
FROM UnknownHours 
GROUP BY ChargeNum 

Uwaga - W przypadku korzystania z UNION ALL jak podano wyżej, to nie działa wolniej niż dwóch zapytań osobno jak ma to żadnego duplikat kontroli.

+0

Słyszałem to wyjątkowo powoli. Czy jest jakiś inny sposób na zrobienie tego? –

+0

Jedyna rzecz, która byłaby prawdopodobnie szybsza, to przechowywanie danych w jednej tabeli, a nie w dwóch. Użyj 'CategoryID = NULL' dla nieznanych godzin. –

+4

@Matthew: Gdzie to usłyszałeś? 'union all' jest absolutnie szybkie. – Eric

11

W planowanej mocy, masz drugi suma ostatni wiersz nieprawidłowe, powinien on wynosić 40 zgodnie z danymi zawartymi w tabelach, ale tutaj jest kwerenda:

Select ChargeNum, CategoryId, Sum(Hours) 
From (
    Select ChargeNum, CategoryId, Hours 
    From KnownHours 
    Union 
    Select ChargeNum, 'Unknown' As CategoryId, Hours 
    From UnknownHours 
) As a 
Group By ChargeNum, CategoryId 
Order By ChargeNum, CategoryId 

I tu jest wyjście :

ChargeNum CategoryId 
---------- ---------- ---------------------- 
111111  1   40 
111111  2   50 
111111  Unknown 70 
222222  1   40 
222222  Unknown 25.5 
+0

Bardzo dziękuję, to było to, czego potrzebowałem, aby rozwiązać mój problem! :) – Alexander

1

czy możemy pójść o krok dalej i powiedzieć, że chce tylko zobaczyć rzędy po połączeniu, które mają co najmniej 50 godzin ... próbowałem, ale pojawia się błąd, że nie może znaleźć SumHours ...

Select ChargeNum, CategoryId, Sum(Hours) As SumHours 
From (
    Select ChargeNum, CategoryId, Hours 
    From KnownHours 
    Union 
    Select ChargeNum, 'Unknown' As CategoryId, Hours 
    From UnknownHours 
) As a 
WHERE (SumHours>=50) 
Group By ChargeNum, CategoryId 
Order By ChargeNum, CategoryId 

Więc próbowałem

Select ChargeNum, CategoryId, Sum(Hours) As SumHours 
From (
    Select ChargeNum, CategoryId, Hours 
    From KnownHours 
    Union 
    Select ChargeNum, 'Unknown' As CategoryId, Hours 
    From UnknownHours 
) As a 
WHERE (Hours>=50) 
Group By ChargeNum, CategoryId 
Order By ChargeNum, CategoryId 

Ale to nie daje sumę godzin na obu tablicach ...