När du lägger till ytterligare en tabell kan du påverka antalet rader och när det händer kommer aggregationer också att påverkas. För att undvika detta aggregerar detaljtabellen så att det bara kan finnas en rad per beställning, då kommer de andra aggregeringarna att förbli konsekventa.
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
REDIGERA
Använd inte "23:59" som slutpunkt för ett datumintervall, som inte är korrekt och kan leda till felaktiga resultat. Det finns ett väldigt enkelt och mer exakt alternativ som bara kräver att du slutar använda "mellan". Dessutom är '12/31/2015 23:59' INTE ett säkert sätt att ange ett datum/tidsvärde. Använd "20160101" som ÄR det säkraste bokstavliga formatet i 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'