我有以下查询,在两个表(客户和订单)上完成连接时效果很好。所有计算都是正确的。
SELECT
Customers.EmailAddress
,COUNT(Orders.OrderID) AS 'overall NumOrders'
,SUM(Orders.PaymentAmount) AS 'overall TotalOrdered'
,COUNT(case when Orders.OrderDate >= '20170101' then Orders.OrderID end) AS '2017 NumOrders'
,SUM( case when Orders.OrderDate >= '20170101' then Orders.PaymentAmount end) AS '2017 TotalOrdered'
,COUNT(case when Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND '12/31/2015 23:59' THEN Orders.OrderID end) AS '2015 NumOrders'
,SUM(case when Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND '12/31/2015 23:59' then Orders.PaymentAmount end) AS '2015 TotalOrdered'
FROM Customers
JOIN Orders ON Customers.Customerid = Orders.Customerid
WHERE
Orders.OrderStatus NOT IN ('Cancelled','Payment Declined')
AND Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND getdate()
GROUP BY
Customers.EmailAddress
正确的结果:
Emailaddress|overallnumorders|overalltotalordered|2017numorder|2017totalordered| 2015numorder|2015totalordered
xyz@gmail.com 1 23.99 0 0 1 23.99
但是当我在上面的查询中添加3个表(customers,orders,orderdetails)时,我的值增加了一倍
SELECT
Customers.EmailAddress
,COUNT(Orders.OrderID) AS 'overall NumOrders'
,SUM(Orders.PaymentAmount) AS 'overall TotalOrdered'
SUM((OrderDetails.Vendor_Price) * (OrderDetails.Quantity) ) AS TotalCost,
,COUNT(case when Orders.OrderDate >= '20170101' then Orders.OrderID end) AS '2017 NumOrders'
,SUM( case when Orders.OrderDate >= '20170101' then Orders.PaymentAmount end) AS '2017 TotalOrdered'
,COUNT(case when Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND '12/31/2015 23:59' THEN Orders.OrderID end) AS '2015 NumOrders'
,SUM(case when Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND '12/31/2015 23:59' then Orders.PaymentAmount end) AS '2015 TotalOrdered'
FROM Customers
JOIN Orders ON Customers.Customerid = Orders.Customerid
JOIN Orderdetails ON Orders.Orderid=Orderdetails.Orderid
WHERE
Orders.OrderStatus NOT IN ('Cancelled','Payment Declined')
AND Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND getdate()
GROUP BY
Customers.EmailAddress
结果不正确:
Emailaddress|overallnumorders|overalltotalordered|totalcost|2017numorder|2017totalordered| 2015numorder|2015totalordered
xyz@gmail.com 2 47.98 11.99 0 0 2 47.98
为什么在第三个表上进行连接是在改变计算?在哪里我想要正确的结果:
Emailaddress|overallnumorders|overalltotalordered|totalcost|2017numorder|2017totalordered| 2015numorder|2015totalordered
xyz@gmail.com 1 23.99 11.99 0 0 1 23.99
答案 0 :(得分:0)
当您添加另一个表时,您可以影响行数,当发生这种情况时,聚合也会受到影响。为避免这种情况聚合详细信息表,以便每个订单只能有一行,那么其他聚合将保持一致。
SELECT
Customers.EmailAddress
, COUNT(Orders.OrderID) AS 'overall NumOrders'
, SUM(Orders.PaymentAmount) AS 'overall TotalOrdered'
, SUM(od.totalcost) AS totalcost
, COUNT(CASE WHEN Orders.OrderDate >= '20170101' THEN Orders.OrderID END) AS '2017 NumOrders'
, SUM(CASE WHEN Orders.OrderDate >= '20170101' THEN Orders.PaymentAmount END) AS '2017 TotalOrdered'
, COUNT(CASE WHEN Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND '12/31/2015 23:59' THEN Orders.OrderID END) AS '2015 NumOrders'
, SUM(CASE WHEN Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND '12/31/2015 23:59' THEN Orders.PaymentAmount END) AS '2015 TotalOrdered'
FROM Customers
JOIN Orders ON Customers.Customerid = Orders.Customerid
JOIN (
SELECT
Orderid
, SUM((Vendor_Price) * (Quantity)) AS totalcost
FROM OrderDetails
GROUP BY
Orderid
) od ON Orders.Orderid = od.Orderid
WHERE Orders.OrderStatus NOT IN ('Cancelled', 'Payment Declined')
AND Orders.OrderDate BETWEEN ' 01/01/2015 00:00' AND GETDATE()
GROUP BY
Customers.EmailAddress
请不要使用" 23:59"作为日期范围的终点,这不准确,可能导致错误的结果。有一个简单而准确的替代方案,只需要你停止使用"之间的#34;。另外' 12/31/2015 23:59'是不指定日期/时间值的安全方式。使用' 20160101'哪个 IS 是SQL Server YYYYMMDD
中最安全的文字格式。
, COUNT(CASE WHEN Orders.OrderDate >= '20150101' AND Orders.OrderDate < '20160101' THEN Orders.OrderID END) AS '2015 NumOrders'
, SUM(CASE WHEN Orders.OrderDate >='20150101' AND Orders.OrderDate < '20160101' THEN Orders.PaymentAmount END) AS '2015 TotalOrdered'