简体   繁体   中英

How to write SQL with count and group by common fields from two tables

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!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM