2009-04-24 11 views
9

Ich suchte nach einer einfachen Funktion, um die Woche des Monats (anstelle der einfachen Woche des Jahres) in einer MySQL-Abfrage zu erhalten.Funktion für die Woche des Monats in Mysql

Das Beste, was ich tun konnte, war:

WEEK(dateField) - WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField)-1 DAY)) + 1 

Ich würde gerne wissen, ob ich das Rad neu zu erfinden hier bin, und wenn es eine einfache und saubere Lösung?

Antwort

12

AFAIK, es gibt keinen Standard in der ersten Woche des Monats.

Erste Woche des Jahres ist die Woche mit Jan 4th.

Wie definieren Sie die erste Woche des Monats?

UPDATE:

Sie benötigen Ihre Abfrage wie folgt zu umschreiben:

SELECT WEEK(dateField, 5) - 
     WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField) - 1 DAY), 5) + 1 

, so dass die Übergänge Jahr richtig gehandhabt werden, und die Wochen beginnen am Monday.

Andernfalls ist Ihre Abfrage in Ordnung.

+0

Ich denke, es ist vielleicht nicht die allgemeinste Lösung, aber für was ich brauche, beginnt eine Woche an einem Montag. Sagen wir, der 1. des Monats fällt auf einen Sonntag, dieser Sonntag würde als Woche 1 zählen. Wenn das Sinn macht ... – YiSh

8

Es gibt eine Alternative, die manchmal in Berichtsdatenbanken verwendet wird. Es ist eine Tabelle zu erstellen, nennen wir sie ALMANAC, die eine Zeile pro Datum (den Schlüssel) hat und jedes benötigte Attribut des Datums hat, das für die Berichterstellung nützlich sein könnte.

Zusätzlich zu der Spalte der Woche des Monats, könnte es eine Spalte geben, ob das Datum ein Firmenurlaub ist und solche Sachen. Wenn Ihr Unternehmen ein Geschäftsjahr hat, das im Juli oder in einem anderen Monat beginnt, können Sie das Geschäftsjahr, den Steuermonat, die Steuerwoche usw., zu denen jedes Datum gehört, einschließen.

Dann schreiben Sie ein Programm, um diese Tabelle aus der Luft zu füllen, angesichts einer Reihe von Daten zu bevölkern. Sie fügen alle verrückten Kalenderberechnungen nur einmal in dieses Programm ein.

Wenn Sie dann das Attribut für ein Datum in einer anderen Tabelle kennen müssen, führen Sie einfach einen Join aus und verwenden Sie die Spalte. Ja, es ist ein weiterer Beitritt. Und nein, diese Tabelle ist nicht normalisiert. Aber es ist immer noch ein gutes Design für bestimmte sehr spezielle Bedürfnisse.

0

Meine Lösung mit einer Woche beginnt an einem Sonntag.

SELECT (1 + ((DATE_FORMAT(DATE_ADD(LAST_DAY(DATE_ADD('2014-07-17', 
    INTERVAL -1 MONTH)), INTERVAL 1 DAY),'%w')+1) + 
    (DATE_FORMAT('2014-07-17', '%d')-2)) DIV 7) "week_of_month"; 
1

(Nur für zukünftige Leser zu klären: diese Antwort auf diese alte Frage wegen einer Prämie hinzugefügt wurde, dass die aktuelle Antwort impliziert nicht befriedigend war, so habe ich diese Lösung/definition mit zusätzlichen "Konfigurationsoptionen" für alle Arten von Situationen.)

Es gibt keine Standarddefinition für die Week of month, sondern eine allgemeine Lösung wäre die folgende Formel, dass Sie Ihren Bedürfnissen konfigurieren können:

select (dayofmonth(dateField) + 6 + (7 - "min_days_for_partial_week") 
     - (weekday(datefield) - "weekday_startofweek" + 7) MOD 7) DIV 7 as week_of_month; 

wo

  • "weekday_startofweek" muss sein ersetzt durch den Wochentag, an dem Sie der erste Tag der Woche sein möchten (0 = Monday, 6 = Sunday).
  • "min_days_for_partial_week" ist die Anzahl der Tage, die die erste Woche als Woche 1 zählen muss (Werte 1 bis 7). Gemeinsame Werte sind 1 (der erste Tag des Monats ist immer Woche 1), 4 (das wäre ähnlich wie "iso Woche des Jahres", wo die erste Woche des Jahres die Woche ist, die den Donnerstag enthält, so hat mindestens 4 Tage) und 7 (Woche 1 ist die erste komplette Woche).

Diese Formel gibt die Werte 0 an 6 zurück. 0 bedeutet, dass die aktuelle Woche eine Teil Woche ist das nicht genug Tage als Woche 1, zu zählen hat und 6 kann nur passieren, wenn Sie Teil Wochen mit weniger als 3 Tagen erlauben Woche 1.

Beispiele zu sein:

Wenn der erste Tag der Woche Montag ("weekday_startofweek" = 0) und Woche 1 sollte immer eine ganze Woche ("min_days_for_partial_week" = 7) sein, wird dies zu

select (dayofmonth(dateField) + 6 - weekday(datefield)) DIV 7 as week_of_month; 

Eg vereinfachen, für 2016-06-02 Sie 0 bekommen, weil Juni 2016 begann mit einem Mittwoch y und für 2016-06-06 werden Sie 1 bekommen, da dies der erste Montag im Juni 2016.

Ihre Formel zu emulieren, wo der erste Tag der Woche ist immer Woche 1 ("min_days_for_partial_week" = 1) und die Woche beginnt mit Sonntag ("weekday_startofweek" = 6), wird diese

select (dayofmonth(dateField) + 12 - (weekday(datefield) + 1) MOD 7) DIV 7 as week_of_month; 

sein Obwohl Sie, dass richtig in 2 Jahren wissen, kommentieren möchten, wo Ihre Konstanten kam.