Reputation: 5736
I have two tables in SQL Server 2008 R2:
Store: Record:
-------------- ------------------------
Shape ID PickedShape Finished
Circle 1 Circle Y
Circle 2 Circle N
Circle 3 Square N
Square 1 Square N
Square 2 Oval Y
Triangle 1 Oval Y
I want to write a SQL query to output all the possible shapes and their counts across the two tables. I can write it in a silly way, like
select
'Circle', (select count(1) from Store where Shape = 'Circle'),
(select count(1) from Record where PickedShape = 'Circle'),
(select count(1) from Record where Finished = 'Y' and PickedShape = 'Circle')
UNION
select
'Square', (select count(1) from Store where Shape = 'Square'),
(select count(1) from Record where PickedShape = 'Square'),
(select count(1) from Record where Finished = 'Y' and PickedShape = 'Square')
UNION...
and go on, but that just silly and not efficient.
I think a more clever way is to use group by. Since some people may not like spoon feeding others, so here is what I tried
SELECT
Shape, COUNT(Shape) AS Available, Picked, Finished
FROM
Store
FULL JOIN
(SELECT PickedShape, COUNT(1) As Picked, SUM(CASE WHEN Finished='Y' THEN 1 ELSE 0 END) AS Finished
FROM Record
GROUP BY PickedShape) t2 ON Store.Shape = t2.PickedShape
GROUP BY
Shape, Picked, Finished
and the output is
Shape Available Picked Finished
NULL 0 2 2
Circle 3 2 1
Square 2 2 0
Triangle 1 NULL NULL
You can see where the problems are.
First I want to have 'Oval' under Shape instead of NULL. Using FULL JOIN gives me all the variations in both the tables, but not showing them...
Second, I want Picked and Finished to show 0 instead of NULL for the missing ones.
Third, I want the SQL to be more efficient if possible.
How do you solve those problems?
Thank you!
Upvotes: 2
Views: 1146
Reputation: 16904
I a little bit modified your query In first query you grouped by Shape, but 'Oval' not exists in first query. Hence Shape receive from derived query.Triangle not exists in derived query, hence its quantity equals 0.
SELECT
COALESCE(Shape, t2.PickedShape) AS Shape, COUNT(Shape) AS Available,
ISNULL(Picked, 0) AS Picked, ISNULL(Finished, 0) AS Finished
FROM
Store
FULL JOIN
(SELECT PickedShape, COUNT(1) As Picked, SUM(CASE WHEN Finished='Y' THEN 1 ELSE 0 END) AS Finished
FROM Record
GROUP BY PickedShape) t2 ON Store.Shape = t2.PickedShape
GROUP BY
Shape, t2.PickedShape, Picked, Finished
Upvotes: 1