Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Tổng hợp các hàm trên nhiều bảng không cho kết quả chính xác

Khi bạn thêm một bảng khác, bạn có thể ảnh hưởng đến số lượng hàng và khi điều đó xảy ra, các tổng hợp cũng sẽ bị ảnh hưởng. Để tránh điều này, bảng chi tiết tổng hợp để chỉ có thể có một hàng cho mỗi đơn đặt hàng, sau đó các tổng hợp khác sẽ vẫn nhất quán.

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

CHỈNH SỬA

Vui lòng không sử dụng "23:59" làm điểm kết thúc cho một phạm vi ngày, điều này không chính xác và có thể dẫn đến kết quả không chính xác. Có một giải pháp thay thế đơn giản và chính xác hơn chỉ yêu cầu bạn ngừng sử dụng "between". Ngoài ra, '12/03/2015 23:59' là KHÔNG một cách an toàn để chỉ định giá trị ngày / giờ. Sử dụng '20160101' mà IS định dạng chữ ate an toàn nhất trong 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. máy chủ sql một hàng nhiều cột thành một cột

  2. tên cột hoặc số ... không khớp với định nghĩa bảng trong bảng được tạo bởi tập lệnh tạo. Lỗi hiển thị trong khi chèn hàng từ bảng này sang bảng khác

  3. cách tính số ngày trong năm trong sql server 2008

  4. Chuyển đổi nvarchar sang bigint trong Sql server 2008

  5. Làm thế nào để thực hiện một khóa hàng?