如何使用两个表中的公共字段用count和group编写SQL

时间:2012-11-09 06:55:08

标签: sql join count group-by sql-server-2008-r2

我在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

我想编写一个SQL查询来输出两个表中所有可能的形状及其计数。我可以用愚蠢的方式写它,比如

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...

继续,但这只是愚蠢而且效率不高。

我认为更聪明的方法是使用group by。因为有些人可能不喜欢用勺子喂他人,所以这就是我试过的。

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

,输出

Shape   Available   Picked  Finished
NULL        0       2       2
Circle      3       2       1
Square      2       2       0
Triangle    1       NULL    NULL

你可以看到问题所在。

首先,我想在Shape下使用'Oval'而不是NULL。使用FULL JOIN为我提供了两个表中的所有变体,但没有显示它们......

其次,我希望Picked and Finished为缺失的那些显示0而不是NULL。

第三,如果可能的话,我希望SQL更有效率。

你如何解决这些问题?

谢谢!

1 个答案:

答案 0 :(得分:1)

我稍微修改了你的查询 在第一个查询中,您按形状分组,但第一个查询中不存在“椭圆”。因此,Shape派生自派生查询。导出查询中不存在三角形,因此其数量等于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