sql >> データベース >  >> RDS >> Sqlserver

複数のテーブルの集計関数で正しい結果が得られない

    別のテーブルを追加すると、行数に影響を与える可能性があり、その場合、集計も影響を受けます。この詳細テーブルの集計を回避して、注文ごとに 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'
    



    1. 動的テーブル名を使用したOracleデータベースのクエリ

    2. MacOS10.10でtnsnames.oraを使用してROracleを使用してOracleデータベースに接続します

    3. bcp:エラー =[Microsoft][SQL Server Native Client 10.0]文字列データ、右側の切り捨て

    4. WHERESELECTサブクエリエラーを伴うMYSQLアップデート