Группировать по дням и до сих пор показывать дни без строк? - PullRequest
4 голосов
/ 04 февраля 2011

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

Возможно ли это сделать только с помощью SQL?

Пример:

SELECT logTime, COUNT(*) FROM logs WHERE logTime >= '2011-02-01' AND logTime <= '2011-02-04' GROUP BY DATE(logTime);

Возвращает что-то вроде этого:

+---------------------+----------+
| logTime             | COUNT(*) |
+---------------------+----------+
| 2011-02-01          |        2 |
| 2011-02-02          |        1 |
| 2011-02-04          |        5 |
+---------------------+----------+
3 rows in set (0,00 sec)

Я бы тоже хотел показать день 2011-02-03.

Ответы [ 4 ]

5 голосов
/ 04 февраля 2011

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

Вы можете создать таблицу календаря и присоединиться к ней,

create table calendar (
    day date primary key,
);

Заполните эту таблицу датами (легко с помощью хранимой процедуры или просто некоторого общего сценария) примерно до 2038 года, и что-то еще, вероятно, сломает unitl, что станет проблемой.

Ваш запрос становится, например,

SELECT logTime, COUNT(*) 
  FROM calendar cal left join logs l on cal.day = l.logTime 
WHERE day >= '2011-02-01' AND day <= '2011-02-04' GROUP BY day;

Теперь вы можете расширить таблицу календаря другими столбцами, в которых указаны месяц, год, неделя и т. Д., Чтобы вы могли легко создавать статистику для других единиц времени. (и пуристы могут утверждать, что таблица календаря будет иметь первичный ключ целочисленного идентификатора, на который ссылается таблица журналов вместо даты)

5 голосов
/ 04 февраля 2011

Для этого вам нужно иметь таблицу (или производную таблицу), которая содержит даты, к которым вы затем можете присоединиться, используя LEFT JOIN.

SQL работает по концепции математических множестви, если у вас нет набора данных, ВЫБРАТЬ нечего.

Если вам нужна дополнительная информация, пожалуйста, прокомментируйте соответственно.

0 голосов
/ 26 сентября 2018
DECLARE @TOTALCount INT
DECLARE @FromDate DateTime = GetDate() - 5
DECLARE @ToDate DateTime = GetDate()

SET @FromDate = DATEADD(DAY,-1,@FromDate)
Select  @TOTALCount= DATEDIFF(DD,@FromDate,@ToDate);

WITH d AS 
        (
          SELECT top (@TOTALCount) AllDays = DATEADD(DAY, ROW_NUMBER() 
            OVER (ORDER BY object_id), REPLACE(@FromDate,'-',''))
          FROM sys.all_objects
        )
SELECT AllDays From d
0 голосов
/ 04 февраля 2011

Я не уверен, если это проблема, которая должна быть решена с помощью SQL. Как показали другие, это требует ведения второй таблицы, которая содержит все отдельных дат данного промежутка времени, который должен обновляться каждый раз, когда промежуток времени увеличивается (который, по-видимому, «всегда», если промежуток времени - текущее время.

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

EXECUTE QUERY `SELECT logTime, COUNT(*) FROM logs WHERE logTime >= '2011-02-01' AND logTime <= '2011-02-04' GROUP BY DATE(logTime);`

FOREACH row IN query result
  WHILE (date in next row) - (date in this row) > 1 day THEN
    CREATE new row with date = `date in this row + 1 day`, count = `0`
    INSERT new row IN query result AFTER this row
    ADVANCE LOOP INDEX TO new row (`this row` is now the `new row`)
  END WHILE
END FOREACH

или что-то в этом роде

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