Группа SQL по дате, но получать даты без записей тоже

Есть ли простой способ сделать GROUP BY DATE(timestamp), который включает все дни в периоде времени, независимо от того, есть ли какие-либо записи, связанные с этой датой?

По сути, мне нужно создать такой отчет:

24 Dec - 0 orders
23 Dec - 10 orders
22 Dec - 8 orders
21 Dec - 2 orders
20 Dec - 0 orders

Подумал, что нет очевидного способа сделать это, но решил, что спрошу. Спасибо всем, кто откликнулся.

ceejayoz 30.12.2008 20:15
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
2
1
4 906
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Один из способов - создать календарную таблицу и присоединиться к ней.

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

Обратите внимание: я предполагаю, что вы конвертируете метку времени в дату.

Это немного сложно при обслуживании, хотя это более производительно, чем создание SP, динамически генерирующего список.

Vinko Vrsalovic 30.12.2008 19:37

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

Neil Barnwell 30.12.2008 19:42

@Neil, я должен сказать, что согласен, но мне не нравится создавать календарную таблицу на лету, если, конечно, это не нужно делать периодически, а не часто.

LeppyR64 30.12.2008 20:01
Ответ принят как подходящий

Вместо использования GROUP BY создайте таблицу (возможно, временную), которая содержит конкретные даты, которые вы хотите, например:

24 Dec
23 Dec
22 Dec
21 Dec
20 Dec

Затем присоедините эту таблицу к таблице заказов.

Хотя это действительный метод, ответ Thangalin ниже программно делает это без необходимости создавать какие-либо новые таблицы.

glasnt 23.06.2009 03:19

Тангаллин сказал: «В Oracle», но OP пометил вопрос «mysql».

ChrisW 23.06.2009 17:48

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

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

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

В SQL Server это было бы так

  Declare @Dates Table (aDate DateTime Not Null)
  Declare @StartDt DateTime Set @StartDt = 'Dec 1 2008'
  Declare @EndDt   DateTime Set @EndDt   = 'Dec 31 2008'
  While @StartDt < @EndDt Begin
    Insert @Dates(aDate) Values(@StartDt)
    Set @StartDt = DateAdd(Day, 1, @StartDt)
  End

   Select D.aDate, Count(O.*) Orders
   From @Dates D Left Join 
      OrderTable O On O.OrderDate = D.aDate
   Group By D.aDate

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

Если вы используете уровень отчетности поверх SQL Server, вы можете просто написать некоторую логику для вставки недостающих дат в интересующий диапазон после возврата данных и перед визуализацией отчета.

Если вы создаете свои отчеты непосредственно из SQL Server, и у вас еще нет хранилища данных, и нет времени или необходимости создавать его прямо сейчас, я бы создал таблицу дат и присоединился к ней. Форматирование, необходимое для объединения и получения желаемого результата, может быть немного неудобным, но оно выполнит свою работу.

Предполагая, что у вас больше заказов, чем дат, может сработать что-то вроде этого:

select date, count(id) as orders
from
(
  SELECT DATE_ADD('2008-01-01', INTERVAL @rn:=@rn+1 DAY) as date from (select @rn:=-1)t, `order` limit 365
) d left outer join `order` using (date)
group by date

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

Corin 22.01.2014 18:56

Есть довольно простой способ сделать это… за исключением того, что я не могу его вспомнить. Но я адаптировал этот запрос из эта ветка:

SELECT 
    DISTINCT(LEFT(date_field,11)) AS `Date`,
    COUNT(LEFT(date_field,11)) AS `Number of events`
FROM events_table
GROUP BY `Date`

Он работает и в MySQL

Это не сработает, так как будут пропущены даты без событий.

ceejayoz 11.10.2014 19:20

Ах, правда. Думаю, этот ответ можно рассматривать только в том случае, если вы готовы программно заполнить пробелы.

fregante 13.10.2014 18:40

Другие вопросы по теме