加入多个表并应用聚合给出错误的结果
Posted
技术标签:
【中文标题】加入多个表并应用聚合给出错误的结果【英文标题】:Joining multiple tables and applying aggegate giving wrong result 【发布时间】:2021-03-03 06:14:02 【问题描述】:我有一个商业案例,当 CountryId 传递给我的 proc 时,我需要获取在该国家/地区设立业务的所有地区、在该地区工作的所有在职销售员工、由该地区目前在职的销售人员。
我的区域表如下所示。
RegionId | Name | CountryId
100 A 1
101 B 4
103 C 1
SalesEmployee 表
Id | EmployeeId | RegionId
1 250 100
2 255 101
3 289 101
员工表
EmployeeId | Active
250 1
255 1
289 0
314 1
销售表
SaleId | EmployeeId| RegionId | Sale
1 100 2 3500
2 101 4 2000
3 100 2 1500
我下面的查询给出了正确的 TotalSales 值,但 TotalUsers 计数不匹配。
Select R.[RegionId], COUNT(SE.[UserId]) AS TotalUsers, SUM(S.[Sales]) AS TotalSales
FROM dbo.[Region] R
INNER JOIN [SalesEmployee] SE
ON R.[RegionId] = SE.[RegionId]
INNER JOIN dbo.[Employee] E
ON E.[EmployeeId] = SE.[EmployeeId]
LEFT JOIN dbo.[Sales] S
ON S.[EmployeeId] = E.[EmployeeId]
WHERE R.[CountryId] = 12 AND E.[Active] = 1
GROUP BY R.[RegionId]
对于 Ex RegionId 100 目前只有 7 名活跃销售员工,但结果给我 89,在我的 Employee 表中可能有更多用户,但其中很少有人可能处于非活动状态,其中很少有人可能在另一个部门工作,为了确保员工是销售员工,员工需要出现在 SalesEmployee 表中并检查员工是否处于活动状态,我需要检查员工表。
问题是 1 个单个用户的姓名可以在销售表中有多个条目,所以当我加入在单个用户上有多个条目的销售表时,TotalEmployees 计数会上升。
【问题讨论】:
【参考方案1】:所以它实际上是一个简单的小修复。
Select R.[RegionId], COUNT(DISTINCT(SE.[UserId])) AS TotalUsers, SUM(S.[Sales]) AS TotalSales
FROM dbo.[Region] R
INNER JOIN [SalesEmployee] SE
ON R.[RegionId] = SE.[RegionId]
INNER JOIN dbo.[Employee] E
ON E.[EmployeeId] = SE.[EmployeeId]
LEFT JOIN dbo.[Sales] S
ON S.[EmployeeId] = E.[EmployeeId]
WHERE R.[CountryId] = 12 AND E.[Active] = 1
GROUP BY R.[RegionId]
这个小小的改变会给你你想要的。
只需将COUNT(SE.[UserId])
更改为COUNT(DISTINCT(SE.[UserId]))
。
【讨论】:
以上是关于加入多个表并应用聚合给出错误的结果的主要内容,如果未能解决你的问题,请参考以下文章
T-SQL GROUP BY 也使用 JOIN、聚合和外部引用错误
使用预先聚合的值加入两个表,既不会导致分组错误,也不会导致聚合错误
将多个单独的查询合并为一个以在Elasticsearch中获取聚合结果