Как мне создать последовательность дат?

0

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

date         action_id
2010-01-01   id00
2010-01-03   id01
2010-01-05   id02

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

Мой план состоит в том, чтобы сделать это.

with dates as (
select [sequence of dates from 2010-01-01 to 2010-02-01] as day)

select day, coalesce(count(distinct action_id), 0) as actions
from dates
left join my_table
on dates.date = my_table.date

Как мне создать последовательность дат?

  • 0
    Вы можете создать таблицу дат со всеми датами в ней и присоединиться к ней.
Теги:

3 ответа

3

Тебе пример показывает CTE. Итак, вы можете использовать рекурсивный CTE:

with recursive dates as (
      select date('2010-01-01') as day
      union all
      select day + interval 1 day
      from dates
      where day < '2010-02-01'
     )
select d.day, count(distinct t.action_id) as actions
from dates d left join
     my_table t
     on d.day = my_table.date
group by d.day;

Обратите внимание, что COUNT() никогда не возвращает NULL, поэтому COALESCE() не требуется.

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

select d.day, count(distinct t.action_id) as actions
from (select date('2010-01-01') + interval (@rn := @rn + 1) - 1 day as day
  from my_table cross join
       (select @rn := 0) params
  limit 31
 ) d left join
     my_table t
     on d.day = my_table.date
group by d.day;
  • 0
    Как сделать общее табличное выражение рекурсивным? Не может найти объект dte
  • 0
    @ tadon11Aaa. , , Более простое решение - исправить опечатку, что я только что сделал.
Показать ещё 2 комментария
0
with dates as
(
select a.Date 
from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) ) DAY as Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d
) a
where a.Date between '<start_date>' and '<end_date>' )
select day, count(distinct action_id) as actions
from dates
left join my_table
on dates.date = my_table.date
0

кажется, вам просто нужно сгруппировать и считать

 select date, count(distinct action_id) as action
 from my_table left join
 dates on dates.date = my_table.date
  group by date

Ещё вопросы

Сообщество Overcoder
Наверх
Меню