使用左连接和不同的总和不正确的值
Posted
技术标签:
【中文标题】使用左连接和不同的总和不正确的值【英文标题】:Using left join and distinct sums incorrect values 【发布时间】:2021-03-18 20:19:39 【问题描述】:我有这个 SQL 查询:
SELECT
COUNT(DISTINCT [sb].[UserId]) AS NumberOfCustomers,
SUM([sb].[ProbabilityAlive]) AS ProbabilityAlive
FROM
sb
WHERE
sb.[Date] = '03/11/2020 00:00:00'
AND sb.[ClientId] = '1112'
此查询返回:
NumberOfCustomers: 50280
ProbabilityAlive: 26107.6830
我最近添加了另一个表,当使用左连接或连接时,我得到的存活概率总和不正确:
SELECT
COUNT(DISTINCT [dbo].[sb].[UserId]) AS NumberOfCustomers,
SUM([dbo].[sb].[ProbabilityAlive]) AS ProbabilityAlive,
SUM([dbo].[AdditionalClvData].[PeakClv]) AS PeakClv
FROM
sb
LEFT JOIN
[dbo].[AdditionalClvData] ON [dbo].[AdditionalClvData].UserId = [dbo].[sb].UserId
WHERE
sb.[CalculationDate] = '03/11/2020 00:00:00'
AND sb[ClientId] = '2'
这个查询现在返回这个结果:
NumberOfCustomers: 50280
ProbabilityAlive: 76949.2354
PeakClv: 44835004.95810
ProbabilityAlive
几乎是原来的三倍。使用左连接时不应该得到相同的总和吗?
【问题讨论】:
我删除了 mysql 标签,因为代码显然是 SQL Server。此外,样本数据和期望的结果也会有所帮助。 为什么数字变了?因为表之间是1:M的关系。所以不,你的期望是不正确的。先求和/计数,然后加入。 如果您删除 distinct 和 aggregation 函数,您可能会发现您的外连接并没有按照您认为的方式进行操作。在聚合之前,我会确保您的查询返回您想要的记录。 Distinct 可能会给您一种温暖模糊的感觉,认为它是正确的,但它也可以隐藏“我正在检索表中的每条记录” FYI 3 列的部分命名将被弃用,应避免使用。为您的对象提供别名并使用这些别名限定您的列。 【参考方案1】:我建议在子查询中预先聚合:
SELECT
COUNT(*) AS NumberOfCustomers,
SUM(s.ProbabilityAlive) AS ProbabilityAlive,
SUM(a.PeakClv) as PeakClv
FROM (
SELECT [UserId], SUM([sb].[ProbabilityAlive]) AS ProbabilityAlive
FROM sb
WHERE sb.[Date] = '20200311'
GROUP BY [UserId]
) s
LEFT JOIN (
SELECT [UserId], SUM([PeakClv]) as PeakClv
FROM [dbo].[AdditionalClvData]
GROUP BY [UserId]
) a ON a.[UserId] = s.[UserId]
【讨论】:
以上是关于使用左连接和不同的总和不正确的值的主要内容,如果未能解决你的问题,请参考以下文章