Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Агрегираните функции на множество таблици не дават правилни резултати

Когато добавите друга таблица, можете да повлияете на броя на редовете и когато това се случи, агрегациите също ще бъдат засегнати. За да избегнете това агрегиране на таблицата с подробности, така че да може да има само един ред на поръчка, тогава другите агрегирания ще останат последователни.

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“ като крайна точка за период от време, това не е точно и може да доведе до неправилни резултати. Има много проста и по-точна алтернатива, която просто изисква да спрете да използвате „между“. Освен това „31.12.2015 г. 23:59“ е НЕ безопасен начин за указване на стойност за дата/час. Използвайте „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'



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Генерирайте хеш на паролата за членство в ASP.Net в чист T-SQL

  2. Кой е най-дългият възможен телефонен номер в световен мащаб, който трябва да взема предвид в SQL varchar(дължина) за телефона

  3. Как да актуализирам колоната за самоличност в SQL Server?

  4. Какво е @@MAX_PRECISION в SQL Server?

  5. Какво означава, когато Statement.executeUpdate() върне -1?