Ich will für jeden Tag im Monat eine Zeile haben in der das Datum steht. Es liegt keine Tabelle zugrunde.
mydate |
---|
2012-11-01 |
2012-11-02 |
… |
2012-11-29 |
2012-11-30 |
Ähnlich, jedoch einfacher wie [MySQL] Virtuelle Tabelle mit allen Daten im Jahr ist es, alle Daten eines Monats zu ermitteln
Und natürlich führen viele Wege nach Rom. Ich habe hier mal 2 Beispiele wie man sowas bewerkstelligen könnte. In beiden ermittle ich alle Tage im November 2012. Das Reusltat ist bei beiden dasselbe
Mit einem Zähler (@day_in_month) für jeden Tag das Datum erstellen
SELECT days_in_month.mydate FROM ( SELECT vars.selected_month, -- Tag hochzählen @day_in_month := @day_in_month + 1 AS day_in_month, -- Ein Datumsstring zusammensetzen und als Datum parsen STR_TO_DATE(CONCAT_WS('-',@day_in_month, vars.selected_month, vars.selected_year), '%d-%m-%Y') AS mydate FROM -- 6^2 Zeilen erstellen: Also 36. (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d1, (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d2, -- Variablen instanzieren. Hier der November 2012 (SELECT @day_in_month :=0, 2012 AS selected_year, 11 AS selected_month) AS vars ) AS days_in_month WHERE -- Nur die gültigen Tage auswählen. Zur erinnerung, wir haben 36 Zeilen.... MONTH(days_in_month.mydate) = days_in_month.selected_month;
Ich erstelle 36 virtuelle Zeilen. Dazu nehme ich 2 UNION-Queries mit je 6 Einträgen die ich unverknüpft zusammenführe.
-- [GRID] -- 6^2 Zeilen erstellen: Also 36. (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d1, (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d2,
Dann erstelle ich ein weiteres Subquery um die Variablen zu setzen
-- VARS] SELECT @day_in_month :=0, -- <Monatsdefinition> -- 2012 AS selected_year, 11 AS selected_month -- </Monatsdefinition> --
Diese werden nun zusammengeführt. Somit habe ich die Initialisierten Variablen und 36 Zeilen. Damit lässt sich wunderschön arbeiten
-- [CALC] SELECT vars.selected_month, -- Tag hochzählen @day_in_month := @day_in_month + 1 AS day_in_month, -- Ein Datumsstring zusammensetzen und als Datum parsen STR_TO_DATE(CONCAT_WS('-',@day_in_month, vars.selected_month, vars.selected_year), '%d-%m-%Y') AS mydate FROM [GRID], [VARS]
Zuerst erhöhe ich immer @day_in_month um 1. Anschliessend setze ich mit dem Jahr, Monat und dem @day_in_month einen Datumsstring zusammen: ##[DATE_STRING] = CONCAT_WS('-',@day_in_month, vars.selected_month, vars.selected_year)## DIeser wird nun noch in ein gültiges Datum gewandelt ##STR_TO_DATE([DATE_STRING], '%d-%m-%Y')##
Am Schluss haben wir natürlich das Problem, dass wir 36 Zeilen haben. Wir brauchen aber nu 28 bis 31, je nach Monat. STR_TO_DATE() kann mit einem Datumsstring '35-11-2012' nix anfangen und gibt da darum NULL zurück. Um nun sicher zu sein, dass ich nur Tage meines ausgewählten Monat habe, setzen ich das ganze nochmals in ein Query und vergleiche den Monat des ermittelten Tages mit dem selektierten Monat.
SELECT days_in_month.mydate FROM [CALC] AS days_in_month WHERE -- Nur die gültigen Tage auswählen. Zur erinnerung, wir haben 36 Zeilen.... MONTH(days_in_month.mydate) = days_in_month.selected_month;
Und zum zeigen das viele Wege nach Rom führen. Das Datum des letzten tages vor dem Monat ermitteln und dann für jeden Tag ein Tag dazurechnen.
SELECT days_in_month.mydate FROM ( SELECT vars.selected_month, -- Tag im Monat hochzählen @act_date := DATE_ADD(@act_date, INTERVAL 1 DAY) AS mydate FROM -- 6^2 Zeilen erstellen: Also 36. (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d1, (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d2, -- Variablen instanzieren ( SELECT @selected_year := 2012, @selected_month := 11 AS selected_month, -- Letzter Tag im Vormonat ermitteln @act_date := DATE_SUB(STR_TO_DATE(CONCAT_WS('-',1, @selected_month, @selected_year), '%d-%m-%Y'), INTERVAL 1 DAY) ) AS vars ) AS days_in_month WHERE -- Nur die gültigen Tage auswählen. Zur erinnerung, wir haben 36 Zeilen.... MONTH(days_in_month.mydate) = days_in_month.selected_month;
Das [GRID] ist dasselbe wie bereits im ersten Beispiel
Hier ist ein wenig mehr. Ich erstelle aus den Parameter gleich das Datum des letzten Tages des Vormonates. Dazu setze ich wieder ein Datum-String auf den ersten des Monats und zieh 1 Tag ab. Somit erhalte ich den letzten Tag des Vormonats in der Variable @act_date.
-- [VARS] SELECT -- <Monatsdefinition> -- @selected_year := 2012, @selected_month := 11 AS selected_month, -- </Monatsdefinition> -- @day_in_month :=0, -- Letzter Tag im Vormonat ermitteln @act_date := DATE_SUB(STR_TO_DATE(CONCAT_WS('-',1, @selected_month, @selected_year), '%d-%m-%Y'), INTERVAL 1 DAY)
Dafür ist die Berechnung nachher umso einfacher. Einfach jedesmal 1 Tag zu @act_date dazurechnen.
-- [CALC] SELECT vars.selected_month, -- Tag im Monat hochzählen @act_date := DATE_ADD(@act_date, INTERVAL 1 DAY) AS mydate FROM [GRID], [VARS]
Das funktioniert genauso wie beim ersten Beispiel.