【问题标题】:Sum of all data different than sum of individual data sets所有数据的总和不同于单个数据集的总和
【发布时间】:2016-12-03 09:42:47
【问题描述】:

什么会导致 SQL Server 2016 Express 在单独运行和一次汇总时返回相同数据集的不同结果?

所有属于销售的交易:

SELECT sum(transactionamount) 
FROM [NewPOS].[dbo].[Transaction] 
WHERE TransactionDateTime >= '2016-11-26 00:00:00' 
  AND TransactionDateTime <= '2017-11-27 0:0:0' 
  AND transactiontype = 0

结果为 134253

所有以现金支付的销售交易:

SELECT sum(transactionamount) 
FROM [NewPOS].[dbo].[Transaction] 
WHERE TransactionDateTime >= '2016-11-26 00:00:00' 
  AND TransactionDateTime <= '2017-11-27 0:0:0' 
  AND transactiontype = 0  
  AND TransactionId IN (SELECT TransactionId 
                        FROM payment 
                        WHERE payment.PaymentType = 0)

结果为 56318.5

所有使用信用卡支付方式进行销售的交易:

SELECT sum(transactionamount) 
FROM [NewPOS].[dbo].[Transaction] 
WHERE TransactionDateTime >= '2016-11-26 00:00:00' 
  AND TransactionDateTime <= '2017-11-27 0:0:0' 
  AND transactiontype = 0  
  AND TransactionId IN (SELECT TransactionId 
                        FROM payment 
                        WHERE payment.PaymentType = 2)

结果为 54054.5

所有使用借记卡支付方式进行销售的交易:

SELECT sum(transactionamount) 
FROM [NewPOS].[dbo].[Transaction] 
WHERE TransactionDateTime >= '2016-11-26 00:00:00' 
  AND TransactionDateTime <= '2017-11-27 0:0:0' 
  AND transactiontype = 0  
  AND TransactionId IN (SELECT TransactionId 
                        FROM payment 
                        WHERE payment.PaymentType = 3)

结果为 28738.5

将 56318.5 + 54054.5 + 28738.5 相加得到 139111.5

139111.5 显然是 != 134253

这三种交易类型的总和有一个额外的4858.5。

验证我没有遗漏付款类型:

SELECT sum(transactionamount) 
FROM [NewPOS].[dbo].[Transaction] 
WHERE TransactionDateTime >= '2016-11-26 00:00:00' 
  AND TransactionDateTime <= '2017-11-27 0:0:0' 
  AND transactiontype = 0  
  AND TransactionId NOT IN (SELECT TransactionId 
                            FROM payment 
                            WHERE payment.PaymentType = 0 
                               OR payment.PaymentType = 2 
                               OR payment.PaymentType = 3)

这可能很简单,但我一直盯着这些结果,计算着东西,无法弄清楚这些数字是怎么加起来的......

编辑:

另一个验证查询,被求和的数据应该与单个查询相同:

SELECT sum(transactionAmount) 
FROM [NewPOS].[dbo].[Transaction] 
WHERE TransactionDateTime >= '2016-11-26 00:00:00' 
  AND TransactionDateTime <= '2017-11-27 0:0:0' 
  AND transactiontype = 0  
  AND TransactionId IN (SELECT TransactionId 
                        FROM payment 
                        WHERE payment.PaymentType = 0 
                           OR payment.PaymentType = 2 
                           OR payment.PaymentType = 3)

此查询也产生 134253

编辑 2:

似乎对多种支付类型的检查未能检测到它——我发现这个问题很可能正是 steenbergh 的回答中描述的问题:

有 -cash 和 +debit 交易(现金返还通过添加 -cash 支付从抽屉中取出现金,以及 +debit 支付全额 + 现金返还..

这会导致非常古怪的数字,而没有过滤掉现金返还交易数字,因为有 交易被添加两次,一次是现金,一次是借方。..

【问题讨论】:

  • 不看实际数据很难说。我最好的猜测是你有多种支付类型的交易。这可以解释结果。
  • 哇..我什至没有想到这一点..虽然有可能这样做,但这种情况很少发生,我会调查那个..
  • 您的人数差异相对较小,这表明这是一个罕见的场合。
  • 2016,抱歉打错了..
  • 你真的确定你没有一些交易 id 超过付款类型吗?

标签: sql sql-server


【解决方案1】:

您的payment 表有多个记录您的一些TransactionIDs。这意味着,例如,人们在同一笔交易中部分使用信用卡和现金支付。

你可以通过

找到这个
select distinct TransactionID, count(*)
from Payment
group by TransactionID having count(*) > 1
order by 2 desc

这将向您显示使用超过 1 种付款方式的所有交易。

这会影响您的总和,因为payment 表只关注这些交易的一部分,而Transactions 中的记录包含全部交易金额。当您检查现金是否用于(部分)付款,然后取出交易的全部金额时,您还可以用信用卡总结已支付的部分。


假设payment 表中有Amount 或类似列,您可以使用JOIN 解决此问题:

SELECT sum(t.transactionamount) as Incorrect
, sum(p.amount) as Correct
FROM [NewPOS].[dbo].[Transaction] t
INNER JOIN [NewPOS].[dbo].[Payment] p on p.TransactionID = t.TransactionID
WHERE t.TransactionDateTime >= '2016-11-26 00:00:00' 
  AND t.TransactionDateTime <= '2017-11-27 0:0:0' 
  AND t.transactiontype = 0
  AND p.PaymentType = 0

进一步细分以展示这些表格如何交互:

SELECT distinct t.TransactionID
, p.PaymentType
, sum(p.amount) as [Amount paid with this type]
FROM [NewPOS].[dbo].[Transaction] t
INNER JOIN [NewPOS].[dbo].[Payment] p on p.TransactionID = t.TransactionID
WHERE t.TransactionDateTime >= '2016-11-26 00:00:00' 
  AND t.TransactionDateTime <= '2017-11-27 0:0:0' 
  AND t.transactiontype = 0

此查询将列出每笔交易使用的付款类型和金额。

为了进一步澄清,我给你画了一张照片:

在任何给定的数据库中,对JOINS 有一个很好的理解是非常重要的。适用于任何类型的系统。阅读 om 'm,学习课程,在 YouTube 上搜索。

【讨论】:

  • 我明白你的意思,但在这种情况下,多交易类型往往极为罕见..
  • @Richard 您现在有 3.5% 的错误,可以完全避免。我强烈建议更改您的查询。我将添加一种方法来做到这一点 - 假设 payment 中有一定数量的东西 - 我的回答。
  • 虽然是一个有效的观点 - 不幸的是这不是问题 - 在那个时间范围内没有使用多种支付类型。
  • 有趣...查询返回的结果与预期不同。在我的原始查询中-我的假设是否正确,即在一次汇总时它只会为每个事务 id 添加一次总数?例如:一笔交易,两笔相同的支付类型,只会添加一次而不是两次
  • @Richard No;它将payment 表中的总数相加。这些是 Transactions 表的总数。您基本上根据日期和状态等从Transactions 中选择您感兴趣的所有交易,然后从payment 中选择每种类型的金额。
猜你喜欢
  • 2019-06-10
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多