2013-03-15 117 views
0

我有一个子查询没有返回我正在查找的结果。在最后一个子查询中,我有3个零件在我的条件中没有日期范围的Order Count,并且它们不返回结果为0.相反,我正在丢失这些零件的所有其他数据。我确信有更好的方法来查询数据,所以这里是我的查询。子查询没有返回正确的结果T-SQL

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 
+0

这将有助于张贴表格cre吃了陈述,样品数据和期望的结果 – 2013-03-15 16:29:49

回答

0

在这里,你去。这应该做到这一点。

  • 因为你总是希望在Top300的所有项目,无论其销售数据,你总是要保持各个子查询的结果在左侧的左侧连接。
  • 您可以将NULL SUM聚合解析为零
  • 日期过滤器需要位于JOIN中,因为您不想限制未加入的Top300项目。如果将它们放在WHERE子句中,那么它将排除未与销售数据合并的Top300商品,因为这些记录的日期将为NULL。

首次设置测试表和数据

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 
+0

我需要添加给我与销售相同问题的位置。并非所有地点都有数据。我怎样才能让这些显示为0值? – tsqln00b 2013-03-15 22:26:21

+0

您应该可以只使用位置表遵循上面的相同模式。尽管,我确实需要至少看到你的“位置”查询来理解你的第二个问题。试着用你的“位置”问题开一个新的问题,并提供一些细节,如上面的销售查询。 – 2013-03-15 22:32:44

+0

我粘贴了包含“我的旧”位置的“新”查询。 – tsqln00b 2013-03-18 14:54:12