Можно ли заставить запрос T-SQL с помощью «Группировать по» возвращать строки, в которых нет данных? - PullRequest
2 голосов
/ 25 мая 2011

Извините, если этот заголовок этого вопроса не очень хорош;Я не уверен, что могу кратко описать это, так что вот более подробная версия:

Я пытаюсь создать отчет, и я на самом деле не уверен, что то, что я хочу сделать, может быть полностью выполненооператор SQL.Вывод, который я хочу получить, будет примерно таким:

Product X
 January:  1 sold
 February : 0 sold

Product Y
 January : 0 sold
 February: 1 sold

Вот базовый оператор SQL (который, кстати, должен работать с SQL Server 2000 и 2008 - не спрашивайте):

SELECT p.productName, 
       SUM(s.salesID) AS numSold, 
       MONTH(s.salesDate) AS monthSold
FROM sales s 
LEFT JOIN products p ON s.productID = p.productID
WHERE s.saleDate > '1/1/2011'
AND s.saleDate < '2/28/2011'
GROUP BY p.productName
ORDER BY p.productName, MONTH(s.salesDate)

Проблема, насколько я понимаю, состоит в том, что этот оператор SQL (справедливо) не возвращает строку для комбинации месяц + продажи за любой месяц, когда продаж не было.Но чтобы упростить вывод этих данных, мне нужно, чтобы оператор возвращал некоторое значение (в идеале 0, но это не обязательно) для любого продукта + месяц, который не содержит данных.

Итак, запрос теперь возвращается так:

productX January 1
ProductY February 1

... и я хотел бы, чтобы он вернулся так:

productX January 1
productX February 0
productY January 0
productY February 1

Это вроде какэто то, что я должен быть в состоянии сделать.Я попробовал что-то вроде этого:

SELECT p.productName, 
       ISNULL(SUM(s.salesID),-100) AS numSold, 
       MONTH(s.salesDate) AS monthSold

... но, возможно, как и ожидалось, это не сработало.

Помощь?(-;

Ответы [ 3 ]

2 голосов
/ 25 мая 2011

Посмотрите на этот недавний вопрос / ответ: SQL-запрос для подсчета числа по месяцам

Если бы у вас была таблица месяцев, вы могли бы использовать ее в качестве базовой таблицы. Вы будете получать записи за каждый месяц.

1 голос
/ 25 мая 2011

Я встречал ситуации, когда можно предположить, что что-то случается хотя бы один раз за сгруппированный отчетный период

Итак, предполагая, что по крайней мере одна продажа будет происходить хотя бы раз в месяц для любого продукта, выможет извлечь месяц и год и сгенерировать последовательность, после которой можно ВЕРНУТЬСЯ к объединенным продажам.

Это может работать не во всех ситуациях (например, в группе в день), но кажется разумным предположить, что вы продаете хотя бывещь в месяц ...

Кроме того, не будет ли COUNT, а не SUMT?

SELECT
    p.productName, 
    COUNT(s.salesID) AS numSold, 
    series.aMonth AS monthSold,
    series.aYear AS yearSold
FROM
   (
    SELECT DISTINCT
        MONTH(salesDate) AS aMonth, YEAR(salesDate) AS aYear
    FROM sales
    WHERE saleDate > '1/1/2011'
    AND saleDate < '2/28/2011'
   ) series
   LEFT JOIN
   sales s ON series.aMonth = MONTH(s.salesDate) AND series.aYear = YEAR(s.salesDate) 
   LEFT JOIN
   products p ON s.productID = p.productID
GROUP BY
   p.productName, series.aMonth, series.aYear
ORDER BY
   p.productName, series.aMonth, series.aYear

Это нормально и для SQL Server 2000+

0 голосов
/ 26 мая 2011

Первый раз "отвечаю" на один из моих собственных вопросов, поэтому извиняюсь, если я облажался, но ...

@ gbn и @Fosco предоставили работоспособные решения, как я упоминал в своем комментарии к посту @ gbn. Это:

  1. Создайте таблицу календаря в вашей базе данных и укажите на нее

  2. Создайте таблицу «календарь» на лету, используя то, что предлагает @Fosco, или что-то более «сексуальное», например CTE (что я не могу использовать, потому что CTE был введен в SQL Server 2005).

Так что я думаю, что получил то, что мне нужно. Надеюсь, это поможет кому-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...