2010-12-16 16 views
2

Ich möchte eine Abfrage schreiben, die für ein beliebiges Startdatum in der Vergangenheit als jede Zeile ein einwöchiges Datumsintervall bis zur Gegenwart hat.Erstellen einer Reihe von Zeiträumen als Zeilen

Zum Beispiel angesichts der Startdatum 13. November 2010, und das aktuelle Datum des 2010.12.16, möchte ich ein Ergebnis gesetzt wie

+------------+------------+ 
| Start  | End  | 
+------------+------------+ 
| 2010-11-15 | 2010-11-21 | 
+------------+------------+ 
| 2010-11-22 | 2010-11-28 | 
+------------+------------+ 
| 2010-11-29 | 2010-12-05 | 
+------------+------------+ 
| 2010-12-06 | 2010-12-12 | 
+------------+------------+ 

Es ist nicht vorbei geht 12, weil der Woche Der Zeitraum, in dem das aktuelle Datum auftritt, ist nicht vollständig.

Ich kann nicht Fuß fassen, wie ich überhaupt anfangen würde, diese Abfrage zu schreiben. Kann ich dies in einer einzigen Abfrage tun? Oder sollte ich Code zum Schleifen verwenden und mehrere Abfragen durchführen?

Antwort

2

Es ist ziemlich schwierig (aber nicht unmöglich), ein solches Ergebnis erstellen dynamisch in MySQL gesetzt, da es noch keine der recursive CTEs, CONNECT BY unterstützen oder generate_series, die ich verwenden würde dies in anderen Datenbanken zu tun.

Hier ist ein alternativer Ansatz, den Sie verwenden können.

Erstellen und füllen Sie eine Tabelle mit allen möglichen Zeilen von einem Datum weit in der Vergangenheit zu einem Datum weit in der Zukunft. Dann können Sie das Ergebnis, das Sie benötigen, einfach erzeugen, indem Sie diese Tabelle mit einer WHERE-Klausel abfragen, indem Sie einen Index verwenden, um die Abfrage effizient zu machen.

Die Nachteile dieses Ansatzes liegen auf der Hand:

  • Es dauert unnötig Speicherplatz.
  • Wenn Sie außerhalb des Bereichs abfragen, mit dem Sie Ihre Tabelle gefüllt haben, erhalten Sie keine Ergebnisse, dh Sie müssen entweder die Tabelle mit genügend Daten füllen, um die Lebensdauer Ihrer Anwendung zu verlängern, oder Sie benötigen eine Skript, um sooft mehr Daten hinzuzufügen.

Siehe auch diese Frage im Zusammenhang:

0

Vorsicht ist dies nur eine Konzeptidee: Ich habe nicht eine MySQL-Installation hier hat, so dass ich es nicht testen kann.

Allerdings würde ich mich auf eine Tabelle mit den ganzen Zahlen stützen, um eine Serie zu emulieren.

Etwas wie:

CREATE TABLE integers_table 
(
    id integer primary key 
); 

durch Gefolgt (Achtung, dieses Pseudo-Code)

INSERT INTO integers_table(0…32767); 

(das genug Wochen für den Rest unseres Lebens :-)

sein sollte Dann

FirstMondayInUnixTimeStamp_Utc= 3600 * 24 * 4 
SecondPerday=3600 * 24 

(seit dem 1. Januar 1970 war ein Donnerstag. Vorsicht, ich habe nicht gecheckt! Ich bin vielleicht ein paar Stunden unterwegs!

)

Und dann

CREATE VIEW weeks 
AS 
    SELECT integers_table.id AS week_id, 
    FROM_UNIXTIME(FirstMondayInUnixTimeStamp_Utc + week_id * SecondPerDay * 7) as week_start 
    FROM_UNIXTIME(FirstMondayInUnixTimeStamp_Utc + week_id * SecondPerDay * 7 + SecondPerDay * 6) as week_end; 
Verwandte Themen