tags:

views:

1612

answers:

2

Say I have two tables:

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

I need to group these hours, ignoring Month, into a single data table so that my expected result is the following:

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

I cannot seem to figure this out. Any help greatly appreciated!

EDIT: I need to sum the hours for each ChargeNum/Category combination. I updated the sample data to reflect this.

+7  A: 

You'll need to use UNION to combine the results of two queries. In your case:

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

Note - If you use UNION ALL as in above, it's no slower than running the two queries separately as it does no duplicate-checking.

lc
I've heard this is exceptionally slow. Is there any other way to do this?
Matthew Jones
The only thing that would be possibly faster is to store the data in one table, not two. Use `CategoryID = NULL` for unknown hours.
lc
@Matthew: Where did you hear that? `union all` is absolutely fast.
Eric
Unfortunately I've already had that conversation... http://stackoverflow.com/questions/1209372/sql-design-accounting-for-unknown-values
Matthew Jones
His original answer was UNION, not UNION ALL. That is what I was referring to.
Matthew Jones
UNIONs and UNION ALLs are OFTEN (if not always) faster than a commensurate "OR" in your filter.
Brian
A: 

In your expected output, you've got the second last row sum incorrect, it should be 40 according to the data in your tables, but here is the 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

And here is the output:

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