按周汇总,即使是空行也是如此

时间:2012-01-17 13:52:04

标签: sql sql-server sql-server-2005

我想按周汇总sales.quantity的总和,并显示周数,即使没有销售。

我已经设置了一个带有1-54的星期表,以使用外部联接强制所有周数通过,但它不起作用。它错过了没有销售的几周。

我的查询是:

SELECT Weeks.WeekNum, SUM(sales.quantity) AS sales
FROM Weeks LEFT OUTER JOIN 
     sales ON Weeks.WeekNum = DATEPART(week, sales.transDate)
WHERE (sales.transDate BETWEEN @fromDate AND @toDate)
GROUP BY Weeks.WeekNum

任何帮助都会受到极大的接受......我可能已经做过蠢事了!

4 个答案:

答案 0 :(得分:2)

where子句WHERE (sales.transDate BETWEEN @fromDate AND @toDate)将删除没有销售的任何周。您可能需要执行子查询来提取事务,然后将其连接到您的周表。

SELECT Weeks.WeekNum, SUM(sales.quantity) AS sales
FROM Weeks LEFT OUTER JOIN 
 (
    SELECT *
    FROM sales 
    WHERE (sales.transDate BETWEEN @fromDate AND @toDate)
 ) sales
    ON Weeks.WeekNum = DATEPART(week, sales.transDate)
GROUP BY Weeks.WeekNum

答案 1 :(得分:1)

我更喜欢这种方法而非子选择

SELECT Weeks.WeekNum, SUM(sales.quantity) AS sales
FROM Weeks
LEFT OUTER JOIN  sales ON (Weeks.WeekNum = DATEPART(week, sales.transDate) AND sales.transDate BETWEEN @fromDate AND @toDate)
GROUP BY Weeks.WeekNum

答案 2 :(得分:1)

正如@ msmucker0527写的那样摆脱WHERE (sales.transDate BETWEEN @fromDate AND @toDate)。 你也可以这样做:

SELECT Weeks.WeekNum, SUM(sales.quantity) AS sales
FROM Weeks W  
     LEFT JOIN sales S ON W.WeekNum = DATEPART(week, S.transDate)
            AND S.transDate BETWEEN @fromDate AND @toDate)
GROUP BY W.WeekNum

此外,此WHERE (sales.transDate BETWEEN @fromDate AND @toDate)保证Index Scan Sales表可以大大减慢您的查询速度。
您最好将列WeekFirstDate datetimeWeekLastDate datetime添加到Weeks表和CREATE NONCLUSTERED INDEX IX_Name ON Sales (TransDate) INCLUDE (quantity)中。在这种情况下,您的查询可以通过以下方式更改:

SELECT Weeks.WeekNum, SUM(sales.quantity) AS sales
FROM Weeks W  
     LEFT JOIN sales S ON S.transDate>=W.WeekFirstDate
                          AND S.transDate<=W.WeekLastDate
                          AND S.transDate BETWEEN @fromDate AND @toDate)
GROUP BY W.WeekNum

答案 3 :(得分:1)

试试这个:

SELECT Weeks.WeekNum, SUM(sales.quantity) AS sales
FROM Weeks 
LEFT JOIN sales 
       ON Weeks.WeekNum = DATEPART(week, sales.transDate) and
          sales.transDate BETWEEN @fromDate AND @toDate
WHERE Weeks.WeekNum BETWEEN DATEPART(week, @fromDate) AND 
                            DATEPART(week, @toDate)
GROUP BY Weeks.WeekNum