我有三个表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 :(得分: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]
答案 1 :(得分: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
答案 2 :(得分:2)
您可以使用join
:
count(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];
如果您希望计数甚至适度大,则不建议这样做。如果计数均为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
。但你只选择了一个人。
答案 3 :(得分:0)
join
将为每个组合创建一个行,并且仅在之后应用分组。因此,正如您所指出的,这不会生成正确的输出。一个技巧是在加入之前执行分组和计算:
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