別のテーブルを追加すると、行数に影響を与える可能性があり、その場合、集計も影響を受けます。この詳細テーブルの集計を回避して、注文ごとに 1 行のみになるようにすると、他の集計は一貫したままになります。
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」を使用しないでください。これは正確ではなく、誤った結果につながる可能性があります。 「between」の使用をやめるだけで済む、非常にシンプルでより正確な代替手段があります。さらに、「2015 年 12 月 31 日 23:59」は NOT です 日付/時刻の値を指定する安全な方法。 IS である「20160101」を使用 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'