使用Left Join时,避免在GROUP BY子句中指定每个表字段

时间:2012-03-10 11:12:45

标签: sql sql-server count group-by left-join

我有一个简单的SQL Server 2008数据库,有两个这样的表:

TableA: 
    (PK)"ID"
    "Field"

TableB:
    (PK)"ID"
    (FK)"ID_TableA"
    "Field"

我想选择TableA中的所有字段以及每TableBTableA中的相应行数:

SELECT A.*, 
       COUNT(B."ID") as "B's number"
FROM "TableA" A
LEFT JOIN "TableB" B ON (A."ID" = B."ID_TableA")
GROUP BY A."ID", A."Field"

这很有效,但我遇到了这个问题:如果TableA被进一步修改(假设我们必须添加另一个Field2列),我必须更新上面的SELECT语句在GROUP BY子句中包含该字段。否则,我在执行操作时收到此错误:

列'TableA.Field2'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中

有没有办法避免这种情况,所以我可以修改我的TableA而不更新上面的所有语句?

3 个答案:

答案 0 :(得分:5)

你可以使用它(表B中的第一个分组依据,然后加入表A):

SELECT A.*, 
       COALESCE("B's number", 0) AS "B's number"
FROM "TableA" A
  LEFT JOIN 
    ( SELECT B."ID_TableA", COUNT(B."ID") as "B's number"
      FROM "TableB" B 
      GROUP BY B."ID_TableA"
    ) AS B ON (A."ID" = B."ID_TableA")

答案 1 :(得分:1)

您可以使用像这样的相关子查询

SELECT A.*
       , (SELECT COUNT(*) FROM "TableB" WHERE "ID_TableA" = A."ID") AS "B's number"
FROM "TableA" A

通常,db引擎优化这些以匹配(或击败)连接性能。

答案 2 :(得分:1)

首先,使用*来允许新列不破坏事情是个坏主意。但我认为你可以做到这一点,得到你想要的结果而不指定A:

的列
SELECT
  A.*, 
  COUNT(B."ID") OVER (PARTITION BY B."ID_TableA") as "B's number"
FROM "TableA" A
LEFT JOIN "TableB" B ON (A."ID" = B."ID_TableA")