2012-01-17 2 views
2

Я хочу суммировать сумму 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 

ЛЮБАЯ помощь будет получено ... это, наверное, что-то глупо, что я сделал!

ответ

2

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

Спасибо, работал отлично. Я не думал об этом отвратительном, где предложение ... – CYMR0

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

Это работает, и оно чище, но другой запрос выполнялся быстрее на моих тестах. Спасибо за помощь – CYMR0

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 datetime и WeekLastDate 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 
+0

Спасибо! Я новичок в SQL, и мне нужно много узнать об индексах и таких вещах. – CYMR0

+0

@ CYMR0 Добро пожаловать. Удачи вам в учебе. –

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

К сожалению, это не сработало. – CYMR0

+0

@ CYMR0: Как он не работал? Что было возвращено запросом? –