Прежде всего, есть некоторые проблемы с вашим запросом:
Ваше предложение SELECT
содержит столбец, который не находится ни в GROUP BY
, ни агрегирован - WM_qtd
.Вы имели в виду SUM(WM_qtd)
, не так ли?
В общем, даты, отформатированные с CONVERT(103)
, не могут быть ни осмысленно ни сопоставлены, ни отсортированы.Я бы посоветовал вам либо использовать другой формат (например, 112
), либо вообще использовать другой метод удаления временной части и применить форматирование позже (только в предложении SELECT
или, возможно, вообще не в SQL).).
Вы фильтруете исходный набор данных с помощью предложения HAVING
, что неэффективно, поскольку все данные должны быть извлечены, сгруппированы и только затем отфильтрованы.В этом конкретном случае было бы лучше отфильтровать данные с помощью предложения WHERE
.
Теперь, что касается вашего вопроса ... Набор результатов, к которому вы стремитесь, в основном перекрестный.продукт всех соответствующих дат и всех соответствующих продуктов (упс, извините за каламбур).Он просто включает некоторую дополнительную информацию, такую как Количество.
Таким образом, вам нужно получить два списка, даты и продукты, перекрестно соединить их, затем вы можете внешне объединить результирующий набор в Tb_InfoProduct
и сгруппировать подата и продукт для получения чисел - так же, как вы уже делаете в своем запросе, только ссылки на столбцы даты и продукта, на которые будут ссылаться ваши предложения GROUP BY
и SELECT
, должны быть в соответствующих производных списках, а не вTb_InfoProduct
таблица.
В целях моего ответа я предполагаю, что подмножество Tb_InfoProduct
, которое вы запрашиваете, содержит все даты и все продукты, которые должны присутствовать в выходных данных, поэтому, чтобыПолучив два списка, я просто выбираю разные даты и разные продукты из подмножества Tb_InfoProduct
.Вот примерное решение во всей его полноте:
SELECT
Date = CONVERT(VARCHAR(10), d.Date, 103),
Product = CASE p.WM_Product
WHEN 1 THEN 'Product A'
WHEN 2 THEN 'Product B'
ELSE 'Product C'
END,
Quantity = SUM(WM_qtd)
FROM (
SELECT DISTINCT Date = DATEADD(DAY, DATEDIFF(DAY, 0, WM_data), 0)
FROM Tb_InfoProduct
WHERE WM_data >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 4, 0)
) d
CROSS JOIN (
SELECT DISTINCT WM_Product
FROM Tb_InfoProduct
WHERE WM_data >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 4, 0)
) p
LEFT JOIN (
SELECT
Date = DATEADD(DAY, DATEDIFF(DAY, 0, WM_data), 0),
WM_Product
FROM Tb_InfoProduct
WHERE WM_data >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 4, 0)
) i ON d.Date = i.Date AND p.WM_Product = i.WM_Product
GROUP BY
d.Date,
p.WM_Product
ORDER BY
d.Date,
p.WM_Product
Если в запрашиваемом подмножестве могут отсутствовать некоторые даты и / или продукты, которые вы бы предпочли включить в выходные данные, вы должны составить список (ы) по-другому.Например, вы можете использовать справочную таблицу Products
для списка продуктов, если она у вас есть, конечно.Что касается дат, вам может понадобиться сгенерировать список дат для данного диапазона, как предложено @OMG Ponies (и этот вопрос может помочь вам в этом: Получить список дат междудве даты с использованием функции ).