2012-03-10 122 views
4

我有一個簡單的SQL Server 2008數據庫包含兩個表這樣,當在GROUP BY子句指定每個表中的字段:避免使用左聯接

TableA: 
    (PK)"ID" 
    "Field" 

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

我想選擇所有TableA中的字段以及每個TableA行中有多少個對應行TableB

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子句中的該字段。

「因爲它不是在聚合函數或GROUP BY子句包含列‘TableA.Field2’在選擇列表中無效」

是:否則,我在執行操作時收到此錯誤有一種方法可以避免這種情況,所以我可以修改我的TableA而不更新所有像上面那樣的語句?

+1

由於該結果從該查詢設置將破壞任何消耗代碼的新列的存在(或者被忽略這樣的代碼),爲什麼不按照最佳實踐,避免'select *'(EXISTS'除外),並指定這個查詢應該返回的列? (如果它被消費代碼忽略,那麼你正在讓SQL Server做更多的工作,並且可能會迫使效率不高的計劃被用於沒有好處) – 2012-03-10 16:01:20

回答

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

您可以使用相關子查詢這樣

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

通常數據庫引擎優化這些匹配(或擊敗)加入表現。

1

首先,使用*來允許新列不會破壞事情是一個壞主意。但我認爲你可以做到這一點,並得到你想要的結果,而不指定的列:

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") 
+0

這將在'TableA'中的每一行返回多次。 – wqw 2012-03-11 20:37:52