Группировать по неделям, как получить пустые недели? - PullRequest
11 голосов
/ 26 января 2011

У меня есть следующий код, который группирует некоторые события (ГГГГ-ММ-ДД ЧЧ: ММ: СС) по неделям, которые отображаются, например, «Y: 2010 - Неделя: 50».

SELECT DATE_FORMAT(date, 'Y:%X - Week:%V') AS regweek, COUNT(*) as number 

это работает хорошо, но я хотел бы вернуться все недели, даже если те, в которых нет событий.

Если на третьей неделе ни одно событие не зарегистрировано, в настоящий момент я получаю:

week 1: 10
week 2: 1
week 4: 2

Хотелось бы получить:

week 1: 10
week 2: 1
week 3: 0
week 4: 2

Ответы [ 3 ]

8 голосов
/ 26 января 2011

SQL не может возвращать строки, которых нет в какой-либо таблице. Чтобы получить желаемый эффект, вам понадобится таблица Weeks (WeekNo INT) с одной строкой на каждую возможную неделю года (которая, IIRC, составляет 53 или 54 возможных недели, в зависимости от того, как вы считаете).

Затем, СОЕДИНИТЕ эту таблицу к своим обычным результатам с OUTER JOIN, чтобы добавить дополнительные недели.

SELECT DATE_FORMAT(date, 'Y:%X - Week:%V') AS regweek, COUNT(date) as number 
    FROM YourTable RIGHT OUTER JOIN Weeks ON WEEK(YourTable.date) = Weeks.WeekNo

[Обновление]: обратите внимание на пользователя COUNT (дата), а не COUNT (*). SQL не будет включать значения NULL в столбец даты при добавлении COUNT. Поскольку в пропущенных неделях не будет ни одной даты, это даст вам 0 событий за эти недели.

1 голос
/ 26 января 2011

В конце я решил решить проблему следующим образом, создав временную таблицу на недели и используя код, который был найден в ответе здесь выше.

CREATE TEMPORARY TABLE weeks (
         id INT
       );
INSERT INTO weeks (id) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (20), (21), (22), (23), (24), (25), (26), (27), (28), (29), (30), (31), (32), (33), (34), (35), (36), (37), (38), (39), (40), (41), (42), (43), (44), (45), (46), (47), (48), (49), (50), (51), (52), (53), (54);
SELECT 
w.id, COUNT(c.issuedate) as numberPerWeek
FROM tableName c RIGHT OUTER JOIN weeks w ON WEEK(c.issuedate) = w.id group by w.id;
0 голосов
/ 26 января 2011

Это своего рода проблема, для которой создаются таблицы чисел / счетчиков - просто простая таблица, которая насчитывает от 0 до чего угодно.В целом они полезны, я всегда рекомендую добавлять их в вашу базу данных.

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

Для быстрого начала:

declare @min    datetime
set     @min    ='2010-01-01'

select
    dateadd(wk, number, @min) as weekDate
from
    numbers
where
    number between 0 and datediff(wk,@min,getdate())

с

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