2015-01-10 95 views
2

我有三個表格TableThreeItems,TableTwoItems和TableOneItems,我需要獲取Person在這些表格中每個表格中的訪問次數。從多個標籤中選擇計數

我試過如下:

SELECT Person.[PersonId] 

, Count(TableOneItemId) as TableOneItemCount 
, Count(TableTwoItemIdId) as TableTwoItemCount 
, Count(TableThreeItemId) as TableThreeItemCount 


FROM [dbo].[Person] 
LEFT JOIN TableOneItem ON TableOneItem.PersonId=Person.PersonId 
LEFT JOIN TableThreeItemId ON TableThreeItemId.PersonId=Person.PersonId 
LEFT JOIN TableTwoItemId ON TableTwoItemId.PersonId=Person.PersonId 
WHERE [Person].PersonId=1 
GROUP BY Person.[PersonId] 

但這並不考慮每一種作爲單獨的計數,但我總是一個錯誤的數。舉例來說,如果他有1 TableOneItem和2個TableTwoItemIds的TableOneItemCount將是2,而TableTwoItemIdCount是2

+0

你能在你的表中添加樣本數據和你所期望的輸出? – SMA

回答

2

您可以通過使用count(distinct)單一join做到這一點:

SELECT Person.[PersonId], 
     Count(distinct TableOneItemId) as TableOneItemCount, 
     Count(distinct TableTwoItemIdId) as TableTwoItemCount, 
     Count(distinct TableThreeItemId) as TableThreeItemCount 
FROM [dbo].[Person] LEFT JOIN 
     TableOneItem 
     ON TableOneItem.PersonId = Person.PersonId LEFT JOIN 
     TableThreeItemId 
     ON TableThreeItemId.PersonId = Person.PersonId LEFT JOIN 
     TableTwoItemId 
     ON TableTwoItemId.PersonId = Person.PersonId 
WHERE [Person].PersonId = 1 
GROUP BY Person.[PersonId]; 

這是如果您希望計數甚至適中,則不推薦使用。如果計數爲100,那麼這將爲每個具有100 * 100 * 100 = 1,000,000中間行的人產生笛卡爾積。處理方式太多。在這種情況下,您希望將計數作爲子查詢。

SELECT Person.[PersonId], TableOneItemCount, TableTwoItemCount, TableThreeItemCount 
FROM [dbo].[Person] LEFT JOIN 
     (select personid, count(TableOneItemId) as TableOneItemCount from TableOneItem where PersonId = 1 group by personid 
    ) t1 
     ON t1.PersonId = Person.PersonId LEFT JOIN 
     (select personid, count(TableTwoItemId) as TableTwoItemCount from TableTwoItem where PersonId = 1 group by personid 
    ) t2 
     ON t2.PersonId = Person.PersonId LEFT JOIN 
     (select personid, count(TableThreeItemId) as TableThreeItemCount from TableThreeItem where PersonId = 1 group by personid 
    ) t3 
     ON t3.PersonId = Person.PersonId 
WHERE Person.PersonId = 1; 

在大多數情況下,你只需使用group by PersonId中的子查詢,而不where計算。但你只選擇一個人。

2
SELECT Person.[PersonId] 

, (SELECT Count(TableOneItemId) from TableOneItem where TableOneItem.PersonId=Person.PersonId) as TableOneItemCount 
, (SELECT Count(TableTwoItemId) from TableTwoItem where TableTwoItem.PersonId=Person.PersonId) as TableTwoItemCount 
, (SELECT Count(TableThreeItemId) from TableThreeItem where TableThreeItem.PersonId=Person.PersonId) as TableThreeItemCount 

FROM [dbo].[Person] 
WHERE [Person].PersonId=1 
3

只需添加一個DISTINCT來計數,就大功告成了:

SELECT Person.[PersonId] 

, Count(DISTINCT TableOneItemId) as TableOneItemCount 
, Count(DISTINCT TableTwoItemIdId) as TableTwoItemCount 
, Count(DISTINCT TableThreeItemId) as TableThreeItemCount 


FROM [dbo].[Person] 
LEFT JOIN TableOneItem ON TableOneItem.PersonId=Person.PersonId 
LEFT JOIN TableThreeItemId ON TableThreeItemId.PersonId=Person.PersonId 
LEFT JOIN TableTwoItemId ON TableTwoItemId.PersonId=Person.PersonId 
WHERE [Person].PersonId=1 
GROUP BY Person.[PersonId] 
0

join ING會爲每種組合創建一個行,分組將只應用之後。所以,如你所說,這不會產生正確的輸出。一個技巧就是你加入之前進行分組和計數

SELECT Person.[PersonId], TableOneItemCount, TableTwoItemCount, TableThreeItemCount 
FROM  Person 
LEFT JOIN (SELECT PersonId, COUNT(*) AS TableOneItemCount 
      FROM  TableOneItem 
      GROUP BY PersonId) t1 ON p.PersonId = t1.PersonId 
LEFT JOIN (SELECT PersonId, COUNT(*) AS TableTwoItemCount 
      FROM  TableTwoItem 
      GROUP BY PersonId) t2 ON p.PersonId = t2.PersonId 
LEFT JOIN (SELECT PersonId, COUNT(*) AS TableThreeItemCount 
      FROM  TableThreeItem 
      GROUP BY PersonId) t3 ON p.PersonId = t3.PersonId 
WHERE  [Person].PersonId = 1 
+0

您在連接條件中的PeronsId上進行了有效篩選..您不需要「按組」進行分組。另外,您應該考慮外部選擇中的空值。即。 'SELECT Person。[PersonId],COALESCE(TableOneItemCount,0)TableOneItemCount,COALESCE(TableTwoItemCount,0)TableTwoItemCount,COALESCE(TableThreeItemCount,0)TableThreeItemCount' –