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

StackOverflow https://stackoverflow.com/questions/400759

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

24 Dec - 0 orders
23 Dec - 10 orders
22 Dec - 8 orders
21 Dec - 2 orders
20 Dec - 0 orders
Это было полезно?

Решение

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

24 Dec
23 Dec
22 Dec
21 Dec
20 Dec

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

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

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

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

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

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

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

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

если вы делаете это в хранимой процедуре, вы можете создать временную таблицу или табличную переменную (я не знаю возможностей 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 
    DISTINCT(LEFT(date_field,11)) AS `Date`,
    COUNT(LEFT(date_field,11)) AS `Number of events`
FROM events_table
GROUP BY `Date`

Это работает и в MySQL

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top