有效地包含不在SQL查询的Group By中的列

时间:2012-07-06 20:37:19

标签: sql sql-server aggregate-functions

鉴于

表A

Id   INTEGER
Name VARCHAR(50)

表B

Id   INTEGER
FkId INTEGER  ; Foreign key to Table A

我希望计算每个FkId值的出现次数:

SELECT FkId, COUNT(FkId) 
FROM B 
GROUP BY FkId

现在我只想从Table A输出名称。

这不起作用:

SELECT FkId, COUNT(FkId), a.Name
FROM B b
INNER JOIN A a ON a.Id=b.FkId
GROUP BY FkId

因为a.Name子句中未包含GROUP BY(产生is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause错误)。

重点是从这样的输出移动

FkId  Count
1      42
2      25

像这样输出

FkId  Count  Name
1      42     Ronald
2      22     John

对于该错误消息,SO上有很多匹配,但有些例如https://stackoverflow.com/a/6456944/141172有一些评论,例如“将在桌面上生成3次扫描,而非1,因此无法扩展”。

如何有效地在查询输出中包含加入的Table B(与FkId的关系为1:1)中的字段?

3 个答案:

答案 0 :(得分:12)

您可以尝试这样的事情:

   ;WITH GroupedData AS
   (
       SELECT FkId, COUNT(FkId) As FkCount
       FROM B 
       GROUP BY FkId
   ) 
   SELECT gd.*, a.Name
   FROM GroupedData gd
   INNER JOIN dbo.A ON gd.FkId = A.FkId

创建一个CTE(公用表表达式)来处理Table B的分组/计数,然后将该结果(每FkId一行)加入Table A并获取更多内容Table A中的列到您的最终结果集中。

答案 1 :(得分:2)

您是否尝试将字段添加到论坛?

SELECT FkId, COUNT(FkId), a.Name
FROM B b
INNER JOIN A a ON a.Id=b.FkId
GROUP BY FkId,a.Name

答案 2 :(得分:0)

select t3.Name, t3.FkId, t3.countedFkId from (a t1 
  join (select t2.FkId, count(FkId) as countedFkId from b t2 group by t2.FkId) 
  on t1.Id = t2.FkId) t3;