Summarise by week, even for empty rows

后端 未结 4 662
旧时难觅i
旧时难觅i 2021-01-21 23:14

I want to summarise the sum of sales.quantity by week, and to show the week number even if there are no sales.

I have setup a weeks table with 1-54 in there to use an ou

相关标签:
4条回答
  • 2021-01-21 23:30

    As @msmucker0527 wrote get rid of WHERE (sales.transDate BETWEEN @fromDate AND @toDate). You can do it also this way:

    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
    

    Also, this WHERE (sales.transDate BETWEEN @fromDate AND @toDate) guarantee the Index Scan of Sales table which can greatly slow down your query.
    You'd better include columns WeekFirstDate datetime and WeekLastDate datetime into Weeks table and CREATE NONCLUSTERED INDEX IX_Name ON Sales (TransDate) INCLUDE (quantity). In this case your query can be changed this way:

    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
    
    0 讨论(0)
  • 2021-01-21 23:34

    I prefer this method versus a sub-select

    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
    
    0 讨论(0)
  • 2021-01-21 23:36

    The where clause WHERE (sales.transDate BETWEEN @fromDate AND @toDate) will remove any weeks without sales. You'll likely need to do a subquery to pull the transactions and then join that to your weeks table.

    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
    
    0 讨论(0)
  • 2021-01-21 23:37

    Try this:

    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
    
    0 讨论(0)
提交回复
热议问题