Question

Existe-t-il un moyen simple de créer un GROUP BY DATE (horodatage) incluant tous les jours d'une période, qu'il y ait ou non des enregistrements associés à cette date?

En principe, je dois générer un rapport comme celui-ci:

24 Dec - 0 orders
23 Dec - 10 orders
22 Dec - 8 orders
21 Dec - 2 orders
20 Dec - 0 orders
Était-ce utile?

La solution

Au lieu d'utiliser GROUP BY, créez une table (peut-être une table temporaire) contenant les dates spécifiques que vous souhaitez, par exemple:

24 Dec
23 Dec
22 Dec
21 Dec
20 Dec

Ensuite, joignez cette table à la table Orders.

Autres conseils

En supposant que vous ayez plus d’ordres que de dates, cela pourrait fonctionner:

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

Une méthode consiste à créer une table de calendrier et à la rejoindre.

Je le créerais de manière permanente, puis créerais une tâche qui insèrerait de nouvelles dates. Cela pourrait être fait chaque semaine, chaque jour, tous les mois, etc.

Notez que je suppose que vous convertissez votre horodatage en date.

vous devez générer un jeu de résultats intermédiaire avec toutes les dates que vous souhaitez inclure dans le résultat ...

si vous faites cela dans un proc stocké, vous pouvez créer une table temporaire ou une variable de table (je ne connais pas les capacités de MySQL), mais une fois que vous avez toutes les dates dans une table ou un ensemble de résultats

Joignez simplement les données réelles de la table temporaire, en utilisant une jointure externe

Dans SQL Server, ce serait comme ceci

  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

Dans un entrepôt de données, la méthode utilisée consiste à créer une table contenant toutes les dates et à créer une clé étrangère entre vos données et la table de dates. Je ne dis pas que c'est la meilleure façon de procéder dans votre cas, mais bien que c'est la meilleure pratique dans les cas où de grandes quantités de données doivent être cumulées de nombreuses manières pour les besoins de la création de rapports.

Si vous utilisez une couche de génération de rapports sur SQL Server, vous pouvez simplement écrire une logique pour insérer les dates manquantes dans la plage d'intérêt après le retour des données et avant le rendu de votre rapport.

Si vous créez vos rapports directement à partir de SQL Server et que vous ne disposez pas déjà d'un entrepôt de données et que vous n'avez pas le temps ou besoin de le créer pour l'instant, je créerais un tableau de dates et le joindrais. Le formatage nécessaire pour faire la jointure et obtenir le résultat souhaité peut sembler un peu louche, mais le travail sera fait.

Il existe un moyen assez simple de faire cela & # 8230; sauf que je ne m'en souviens pas. Mais j’ai adapté cette requête de ce fil :

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

Cela fonctionne aussi dans MySQL

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top