0

探している結果を返さないサブクエリがあります。最後のサブクエリでは、条件の日付範囲の注文数がない3つのパーツがあり、結果が0で返されません。代わりに、これらのパーツの他のすべてのデータが失われています。データをクエリするより良い方法があると確信しているので、ここに私のクエリがあります。

    SELECT b.Part, b.Last_12_Mo, b.Last_6_Mo,
       COUNT(sd.SBINV) AS Order_Count
  FROM (
        SELECT a.Part, a.Last_12_Mo,
               ISNULL(SUM(sd.SBQSHP), 0) AS Last_6_Mo
          FROM (
                SELECT t3.Part, ISNULL(SUM(sd.SBQSHP),0) AS Last_12_Mo
                  FROM Top300 AS t3
                  LEFT JOIN SalesData AS sd 
                    ON t3.Part   = sd.SBITEM
                   AND sd.SBINDT > '20120315'
                 GROUP BY t3.Part, sd.SBLOC
                ) AS a 
          LEFT JOIN SalesData AS sd
            ON a.Part       = sd.SBITEM
           AND sd.SBINDT    > '20121015'
         GROUP BY a.Part, a.Last_12_Mo
        ) AS b 
  LEFT JOIN SalesData AS sd
    ON b.Part       = sd.SBITEM
   AND sd.SBINDT    > '20130110'
 GROUP BY b.Part, b.Last_12_Mo, b.Last_6_Mo
 ORDER BY b.Part
4

1 に答える 1

0

どうぞ。これでうまくいくはずです。

  • 売上データに関係なく、常にTop300のすべてのアイテムが必要なため、各サブクエリの結果をLEFTJOINの左側に保持する必要があります。
  • NULLSUM集計をゼロに解決できます
  • 参加しないTop300アイテムを制限したくないので、日付フィルターをJOINに含める必要があります。それらをWHERE句に入れると、それらのレコードの日付がNULLになるため、売上データと結合しないTop300アイテムが除外されます。

最初にテストテーブルとデータを設定します

    IF OBJECT_ID('Top300', 'U') IS NOT NULL DROP TABLE Top300;
    GO
    IF OBJECT_ID('SalesData', 'U') IS NOT NULL DROP TABLE SalesData;
    GO
    CREATE TABLE Top300 (
        Part  varchar(10)
    )
    GO
    CREATE TABLE SalesData (
        SBITEM  varchar(10)
       ,SBQSHP  int
       ,SBINV   int
       ,SBINDT  int
    )
    GO

    INSERT Top300
    SELECT A.*
      FROM (
            SELECT * FROM Top300 WHERE 1=2
            UNION ALL SELECT 'Widget1'
            UNION ALL SELECT 'Widget2'
            UNION ALL SELECT 'Widget3'
            UNION ALL SELECT 'Widget4'
            UNION ALL SELECT 'Widget5'
            UNION ALL SELECT 'Widget6'
           ) A

    INSERT SalesData
    SELECT A.*
      FROM (
            SELECT * FROM SalesData WHERE 1=2
            UNION ALL SELECT 'Widget1', 100, 1000, '20120316'
            UNION ALL SELECT 'Widget2', 100, 1000, '20120316'

            UNION ALL SELECT 'Widget3', 100, 1000, '20121016'
            UNION ALL SELECT 'Widget4', 100, 1000, '20121016'
            UNION ALL SELECT 'Widget5', 100, 1000, '20121016'
           ) A

次に、元のクエリの修正バージョンを実行します

    SELECT b.Part, b.Last_12_Mo, b.Last_6_Mo,
           COUNT(sd.SBINV) AS Order_Count
      FROM (
            SELECT a.Part, a.Last_12_Mo,
                   ISNULL(SUM(sd.SBQSHP), 0) AS Last_6_Mo
              FROM (
                    SELECT t3.Part, ISNULL(SUM(sd.SBQSHP),0) AS Last_12_Mo
                      FROM Top300 AS t3
                      LEFT JOIN SalesData AS sd 
                        ON t3.Part   = sd.SBITEM
                       AND sd.SBINDT > '20120315'
                     GROUP BY t3.Part
                    ) AS a 
              LEFT JOIN SalesData AS sd
                ON a.Part       = sd.SBITEM
               AND sd.SBINDT    > '20121015'
             GROUP BY a.Part, a.Last_12_Mo
            ) AS b 
      LEFT JOIN SalesData AS sd
        ON b.Part       = sd.SBITEM
       AND sd.SBINDT    > '20130110'
     GROUP BY b.Part, b.Last_12_Mo, b.Last_6_Mo
     ORDER BY b.Part

最後に、同じ結果を生成する、より単純で最適化されたクエリを実行してみましょう。

    SELECT b.Part
          ,SUM(CASE WHEN sd.SBINDT > '20120315' THEN sd.SBQSHP ELSE 0 END) as [Last_12_Mo]
          ,SUM(CASE WHEN sd.SBINDT > '20121015' THEN sd.SBQSHP ELSE 0 END) as [Last_6_Mo]
          ,SUM(CASE WHEN sd.SBINDT > '20130110' THEN 1 ELSE 0 END) as [Order_Count]
      FROM Top300 b
      LEFT JOIN SalesData AS sd
        ON b.Part       = sd.SBITEM
       AND sd.SBINDT    > '20120315'
     GROUP BY b.Part
     ORDER BY b.Part
于 2013-03-15T17:13:42.443 に答える