2009-08-04 18 views
41

dire che ho due tabelle:Combinare due tabelle per un'uscita

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 

ho bisogno di gruppo di queste ore, ignorando mese, in un unico tabella dati in modo che il mio risultato previsto è il seguente:

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

Non riesco a capirlo. Qualsiasi aiuto sarebbe molto apprezzato!

MODIFICA: Ho bisogno di sommare le ore per ogni combinazione ChargeNum/Categoria. Ho aggiornato i dati di esempio per riflettere questo.

risposta

65

È necessario utilizzare UNION per combinare i risultati di due query. Nel tuo caso:

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 

Nota - Se si utilizza UNION ALL come in precedenza, non è più lento che le due query separata dal momento che non fa duplicato controllo.

+0

Ho sentito questo è incredibilmente lento. C'è un altro modo di fare questo? –

+0

L'unica cosa che potrebbe essere più veloce è quella di memorizzare i dati in una tabella, non in due. Usa 'CategoryID = NULL' per le ore sconosciute. –

+4

@ Matthew: Dove l'hai sentito? 'union all' è assolutamente veloce. – Eric

11

Nel vostro risultato atteso, hai la seconda somma ultima riga non corretta, dovrebbe essere 40 secondo i dati nelle tabelle, ma qui è la query:

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 

Ed ecco l'output :

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

Grazie mille, questo è quello di cui avevo bisogno per risolvere il mio problema! :) – Alexander

1

Possiamo fare un passo più in là e dire voglio solo vedere righe quando combinato che hanno 50 o più ore ... ho provato questo, ma ottenere un errore che non riesce a trovare 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 

Così ho provato

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 

Ma questo non sta dando la somma delle ore su entrambi i tavoli ...