2012-12-31 27 views
16

Was ist der beste Weg in Mysql, eine Reihe von Daten in einem bestimmten Bereich zu generieren?Generieren einer Reihe von Daten

Die Anwendung, die ich im Auge habe, ist eine Berichtsabfrage zu schreiben, die eine Zeile für jedes Datum zurückgibt, unabhängig davon, ob Daten zu berichten sind. In seiner einfachsten Form:

select dates.date, sum(sales.amount) 
from <series of dates between X and Y> dates 
left join sales on date(sales.created) = dates.date 
group by 1 

Ich habe versucht, einen Tisch mit vielen Terminen erstellen, aber das scheint wie eine schlechte Abhilfe.

Antwort

15

Ich denke, mit einer Kalender Tabelle ist eine gute Idee; Sie können eine Menge Berichts- und Abfragefunktionen erhalten, insbesondere beim Füllen von Datenbereichen mit geringer Dichte.

Ich fand this article mit was scheint ein gutes Beispiel zu sein.

7

Sie eine variable Serie erzeugen Datum verwenden:

Set @i:=0; 
SELECT DATE(DATE_ADD(X, 
INTERVAL @i:[email protected]+1 DAY)) AS datesSeries 
FROM yourtable, (SELECT @i:=0) r 
where @i < DATEDIFF(now(), date Y) 
; 

Nicht sicher, ob dies ist, was Sie versucht haben :) aber.

Nächste Verwendung oben generierte Abfrage als Tabelle left join:

set @i:=0; 

select 
d.dates, 
sum(s.amount) as TotalAmount 
from(
SELECT DATE(DATE_ADD(X, 
INTERVAL @i:[email protected]+1 DAY)) AS dateSeries 
FROM Sales, (SELECT @i:=0) r 
where @i < DATEDIFF(now(), date Y) 
) dates d 
left join Sales s 
on Date(s.Created) = Date(d.dateSeries) 
group by 1 
; 
+0

@Bohemian zu verwenden, das ein schneller Fisch ist zu fangen;) ich auch noch einen Hut brauche: D – bonCodigo

+0

welchen Hut versuchen Sie zu bekommen? – Bohemian

+0

@ Bohemian ** Gangnam Style ** und ** Wo ist er? ** Sie sind herzlich willkommen auf meine tolle Fragen oder tolle Antworten;) Blimey! hahaha, aber es ist * lamer * auf ein weiteres Jahr zu warten: P – bonCodigo

5

Sie können temporäre Tabelle auch verwenden, um Datumsserien zu generieren. Unten finden Sie query:

CREATE TEMPORARY TABLE daterange (dte DATE); 

SET @counter := -1; 
WHILE (@counter < DATEDIFF(DATE(_todate), DATE(_fromdate))) DO 
    INSERT daterange VALUES (DATE_ADD(_fromdate, INTERVAL @counter:[email protected] + 1 DAY)); 
END WHILE; 

SELECT dates.dte, SUM(sales.amount) 
FROM daterange dates 
LEFT JOIN sales ON DATE(sales.created) = dates.date 
GROUP BY dates.dte; 
6

, wenn Sie in einer Situation, wie ich sind, wo temporäre Tabellen erstellen verboten ist, und Einstellung Variablen ist auch nicht erlaubt, aber Sie wollen eine Liste von Daten erzeugen, die in ein bestimmte Zeitraum von, sagt laufendes Jahr etwas Aggregation zu tun, um diesen

select * from 
(select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) gen_date from 
(select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0, 
(select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1, 
(select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2, 
(select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3, 
(select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v 
where gen_date between '2017-01-01' and '2017-12-31' 
Verwandte Themen