Pergunta

Existe uma maneira fácil de fazer um GROUP BY DATE(timestamp) que inclui todos os dias em um período de tempo, independentemente se existem quaisquer registos associados a essa data?

Basicamente, eu preciso gerar um relatório como este:

24 Dec - 0 orders
23 Dec - 10 orders
22 Dec - 8 orders
21 Dec - 2 orders
20 Dec - 0 orders
Foi útil?

Solução

Em vez de usar GROUP BY, fazer uma tabela (talvez uma tabela temporária), que contém as datas específicas que você quer, por exemplo:

24 Dec
23 Dec
22 Dec
21 Dec
20 Dec

Em seguida, junte-se que a tabela para a tabela Pedidos.

Outras dicas

Supondo que você tenha mais encomendas do que datas algo como isso poderia funcionar:

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

Um método é criar uma tabela de calendário e junte-se contra ela.

Gostaria de criar-lo permanentemente, em seguida, criar uma tarefa que irá inserir novas datas, isso poderia ser feito semanalmente, diariamente, mensalmente, etc.

Note, que eu estou supondo que você está convertendo seu timestamp em uma data.

você precisa para gerar um conjunto de resultados intermediário com todas as datas em que você deseja incluir na saída ...

Se você está fazendo isso em um proc armazenado, em seguida, você poderia criar uma tabela temporária ou variável de tabela (não knoiw capacidades do MySQL), mas uma vez que você tem todas as datas em uma tabela ou conjunto de resultados de algum tipo

Apenas se juntar ao dataa real a partir de tabela temporária, utilizando uma associação externa

No SQL Server que seria como este

  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

Em um armazém de dados, o método de tomada é criar uma tabela que contém todas as datas e criar uma chave estrangeira entre os dados ea tabela de data. Eu não estou dizendo que este é o melhor caminho a percorrer no seu caso, só que ele é a melhor prática nos casos em que grandes quantidades de dados precisam ser enrolado em inúmeras maneiras para fins de relatório.

Se você estiver usando uma camada de relatórios sobre SQL Server, você pode simplesmente escrever alguma lógica para inserir as datas em falta dentro da faixa de interesse após os retornos de dados e antes de tornar o seu relatório.

Se você estiver criando seus relatórios diretamente do SQL Server e você ainda não tem um armazém de dados e não há tempo ou necessidade de criar um agora, eu iria criar uma tabela de data e junte-se a ele. A formatação necessária para fazer a juntar-se e obter o resultado que você quer pode ser um pouco frouxo, mas vai fazer o trabalho.

Há uma maneira muito simples de fazer isso ... exceto que eu não me lembro. Mas eu adaptei esta consulta de esta discussão :

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

Ele funciona no MySQL demasiado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top