Der Oracle-Tabellenserver bietet eine integrierte Funktion, TRUNC(timestamp,'DY')
. Diese Funktion konvertiert jeden Zeitstempel des vorherigen Sonntags in Mitternacht. Was ist der beste Weg, um dies in MySQL zu tun?
Oracle bietet auch TRUNC(timestamp,'MM')
an, um einen Zeitstempel am ersten Tag des Monats, in dem er auftritt, in Mitternacht umzuwandeln. In MySQL ist dies ganz einfach:
TIMESTAMP(DATE_FORMAT(timestamp, '%Y-%m-01'))
Aber dieser DATE_FORMAT
Trick wird wochenlang nicht funktionieren. Mir ist die Funktion WEEK(timestamp)
bekannt, aber ich möchte wirklich keine Wochennummer innerhalb des Jahres. Dieses Zeug ist für mehrjährige Arbeit.
Fand es heraus ... es ist ein bisschen umständlich, aber hier ist es.
FROM_DAYS(TO_DAYS(TIMESTAMP) -MOD(TO_DAYS(TIMESTAMP) -1, 7))
Und wenn Ihre Geschäftsregeln besagen, dass Ihre Wochen montags beginnen, ändern Sie das -1
bis -2
.
Bearbeiten
Jahre sind vergangen und ich bin endlich dazu gekommen, dies aufzuschreiben. http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/
Sie können sowohl YEAR(timestamp)
als auch WEEK(timestamp)
verwenden und diese beiden Ausdrücke in SELECT
und die GROUP BY
- Klausel.
Nicht übermäßig elegant, aber funktional ...
Und natürlich können Sie diese beiden Datumsteile auch in einem einzigen Ausdruck kombinieren, d. H. So etwas wie
SELECT CONCAT(YEAR(timestamp), '/', WEEK(timestamp)), etc...
FROM ...
WHERE ..
GROUP BY CONCAT(YEAR(timestamp), '/', WEEK(timestamp))
Bearbeiten : Wie Martin weist darauf hin können Sie auch das YEARWEEK(mysqldatefield)
verwenden Funktion, obwohl seine Ausgabe nicht so augenfreundlich ist wie die längere Formel oben.
Edit 2 [3 1/2 Jahre später!]:YEARWEEK(mysqldatefield)
mit dem optionalen zweiten Argument ( mode
) auf 0 oder 2 ist wahrscheinlich der beste Weg zu complete Wochen aggregieren (dh auch für Wochen, die über den 1. Januar hinausreichen), wenn dies gewünscht wird. Der YEAR() / WEEK()
-Ansatz, der ursprünglich in dieser Antwort vorgeschlagen wurde, bewirkt, dass die aggregierten Daten für diese "Spreizung" Wochen in zwei aufgeteilt werden: eine mit dem vorherigen Jahr, eine mit dem neuen Jahr.
In der Buchhaltung usw. wird häufig ein Clean-Cut jedes Jahr auf Kosten von bis zu zwei Teilwochen, eine an beiden Enden, gewünscht, und aus diesem Grund ist der Ansatz YEAR() / WEEK()
besser.
Die oben akzeptierte Antwort hat bei mir nicht funktioniert, da die Wochen in alphabetischer Reihenfolge und nicht in chronologischer Reihenfolge sortiert wurden:
2012/1
2012/10
2012/11
...
2012/19
2012/2
Hier ist meine Lösung zum Zählen und Gruppieren nach Woche:
SELECT CONCAT(YEAR(date), '/', WEEK(date)) AS week_name,
YEAR(date), WEEK(date), COUNT(*)
FROM column_name
GROUP BY week_name
ORDER BY YEAR(DATE) ASC, WEEK(date) ASC
Erzeugt:
YEAR/WEEK YEAR WEEK COUNT
2011/51 2011 51 15
2011/52 2011 52 14
2012/1 2012 1 20
2012/2 2012 2 14
2012/3 2012 3 19
2012/4 2012 4 19
Sie können die verkettete Jahres- und Wochennummer (200945) mit der Funktion YEARWEEK () abrufen. Wenn ich Ihr Ziel richtig verstehe, sollten Sie die Möglichkeit haben, Ihre mehrjährigen Daten zu gruppieren.
Wenn Sie den tatsächlichen Zeitstempel für den Beginn der Woche benötigen, ist es weniger schön:
DATE_SUB( field, INTERVAL DAYOFWEEK( field ) - 1 DAY )
Bei einer monatlichen Bestellung können Sie die Funktion LAST_DAY () in Betracht ziehen. Die Sortierung erfolgt nach dem letzten Tag des Monats. Dies sollte jedoch der Sortierung nach dem ersten Tag des Monats entsprechen ?
Fügen Sie dies einfach in die Auswahl ein:
DATE_FORMAT($yourDate, \'%X %V\') as week
Und
group_by(week);
Wenn Sie das Datum "Wochenende" benötigen, funktioniert dies ebenfalls. Dadurch wird die Anzahl der Datensätze für jede Woche gezählt. Beispiel: Wenn drei Arbeitsaufträge zwischen (einschließlich) 1/2/2010 und 1/8/2010 erstellt wurden und 5 zwischen (einschließlich) 1/9/2010 und 1/16/2010 erstellt wurden, würde dies Folgendes zurückgeben:
3 08.01.2010
5 1/16/2010
Ich musste die zusätzliche DATE () - Funktion verwenden, um mein Datum/Uhrzeit-Feld abzuschneiden.
SELECT COUNT(*), DATE_ADD( DATE(wo.date_created), INTERVAL (7 - DAYOFWEEK( wo.date_created )) DAY) week_ending FROM work_order wo GROUP BY week_ending;