所有数据的总和不同于各个数据集的总和

时间:2016-12-03 09:42:48

标签: sql sql-server

什么会导致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付款从抽屉中取出现金,以及全额+现金返还的+借记付款..

这会导致真正古怪的数字而不会过滤掉现金返还交易数量,因为 交易会以现金方式一次加一次,而且一次是借记卡。

1 个答案:

答案 0 :(得分:5)

您的payment表有一些TransactionID的多条记录。例如,这意味着人们为同一笔交易部分支付了信用卡和现金。

你可以用

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

这将显示所有使用多种付款方式的交易。

这会影响您的总和,因为payment表仅涉及这些交易的一部分,Transactions中的记录保存完整的交易金额。当您检查现金是否用于(部分)付款,然后获取全部交易金额时,您还可以使用信用卡汇总已支付的部分。

假设Amount表格中有payment列或类似内容,您可以使用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

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

为了进一步澄清,我已经为您画了一张照片: enter image description here

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