sql >> Database teknologi >  >> RDS >> Sqlserver

Aggregerede funktioner på flere tabeller giver ikke korrekte resultater

Når du tilføjer en anden tabel, kan du påvirke antallet af rækker, og når det sker, vil aggregeringer også blive påvirket. For at undgå dette aggregere detaljetabellen, så der kun kan være én række pr. ordre, så vil de andre aggregeringer forblive konsistente.

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

REDIGER

Brug venligst ikke "23:59" som et slutpunkt for et datointerval, der ikke er nøjagtigt og kan føre til forkerte resultater. Der er et gratis simpelt og mere præcist alternativ, som bare kræver, at du stopper med at bruge "mellem". Derudover er '12/31/2015 23:59' IKKE en sikker måde at angive en dato/tidsværdi. Brug '20160101', som ER det sikreste bogstavelige format 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'



  1. CodeIgniter:SQL-revision af alle $this->db->query()-metodekald?

  2. Slet dublerede rækker fra lille tabel

  3. SQLSTATE[23000]:Overtrædelse af integritetsbegrænsning:1452 Kan ikke tilføje eller opdatere en underordnet række:en fremmednøglebegrænsning mislykkes

  4. Brug flere kolonner som unikt id for mysql