I have two (identical for this purpose) tables
ToDoList
ItemBatch | Item abc Pickup sticks abc Tie my shoe xyz Suck my thumb abc Climb a tree
DoneList
ItemBatch | Item abc Tie my shoe
I’m trying to get a count from each of these per [ItemBatch] but not sure if that’s actually possible in one query?
Separately I’d just do
select count(*) from ToDoList where ItemBatch = 'abc' /* repeat for each ItemBatch */ select count(*) from DoneList where ItemBatch = 'abc' /* repeat for each ItemBatch */
and assign to variables in the front-end so I could get the following:
ItemBatch | Total | DoneList | DoneList - ToDoList abc 3 1 2 xyz 1 0 1
Is there a query that can give me that entire output in one fell swoop? I tried joining for starters
select count(cc.[ItemBatch]), count(cq.[ItemBatch]) from ToDoList cc left join DoneList cq on cc.[ItemBatch] = cq.[ItemBatch]
Quickly realised that’s not going to work…
Then I thought about
select (select count(*) from ToDoList where [ItemBatch] = 'abc' ) as Total, (select count(*) from DoneList where [ItemBatch] = 'abc' ) as DoneList
but I can’t figure out how to get all rows outputted for each ItemBatch
in one go, group by
doesn’t work for that last statement:
select (select [ItemBatch], count([ItemBatch]) from ToDoList group by [ItemBatch) as Total, (select [ItemBatch], count([ItemBatch]) from DoneList group by [ItemBatch]) as DoneList
Advertisement
Answer
You should try to use OUTER APPLY
in your case because of the calculation in the SELECT
statement.
The OUTER APPLY operator returns all the rows from the left table expression irrespective of its match with the right table expression. For those rows for which there are no corresponding matches in the right table expression, it contains NULL values in columns of the right table expression.
So, your statement should be:
SELECT cc.ItemBatch, COUNT(*) as Total, ISNULL(dl.DoneListTotal, 0) as DoneList, COUNT(*) - ISNULL(dl.DoneListTotal, 0) as [DoneList - ToDoList] FROM ToDoList cc OUTER APPLY (SELECT COUNT(*) DoneListTotal FROM DoneList cq WHERE cc.ItemBatch = cq.ItemBatch) dl GROUP BY cc.ItemBatch, dl.DoneListTotal;