2009-04-24 11 views
9

Szukałem prostej funkcji, aby uzyskać tydzień miesiąca (zamiast łatwego tygodnia w roku) w zapytaniu mysql.Funkcja na tydzień miesiąca w mysql

Najlepszym mogę wymyślić było:

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

chciałabym wiedzieć, czy mam wymyślać koła tutaj, a jeśli nie jest to prostsze i czystsze rozwiązanie?

Odpowiedz

12

AFAIK, nie ma standardu w pierwszym tygodniu miesiąca.

Pierwszy tydzień roku to tydzień zawierający Jan 4th.

Jak definiujesz pierwszy tydzień w miesiącu?

UPDATE:

Musisz przepisać zapytanie tak:

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

tak że przejścia roku są obsługiwane poprawnie, a tydzień rozpoczyna się Monday.

W przeciwnym razie zapytanie jest prawidłowe.

+0

Domyślam się, że to może nie być najbardziej ogólne rozwiązanie, ale na to, czego potrzebuję, tydzień zaczyna się w poniedziałek. Powiedzmy, że 1 dzień miesiąca przypada w niedzielę, że niedziela będzie liczona jako tydzień 1. Jeśli to ma sens ... – YiSh

8

Istnieje alternatywa, która jest czasami używana w raportowaniu baz danych. Ma stworzyć tabelę, nazwijmy ją ALMANAC, która ma jeden wiersz na datę (klucz) i ma każdy potrzebny atrybut daty, który może być przydatny do celów raportowania.

Oprócz kolumny tydzień w miesiącu może istnieć kolumna dotycząca tego, czy data jest dniem wolnym od pracy, i tym podobne. Jeśli Twoja firma miała rok obrotowy rozpoczynający się w lipcu lub w innym miesiącu, możesz uwzględnić rok podatkowy, miesiąc fiskalny, tydzień podatkowy itp., Do których należy każda data.

Następnie pisze się jeden program, aby wypełnić tę tabelę z powietrza, biorąc pod uwagę zakres dat do wypełnienia. Uwzględniasz wszystkie szalone kalkulacje kalendarza tylko raz w tym programie.

Następnie, gdy potrzebujesz poznać atrybut daty dla innej tabeli, po prostu wykonaj połączenie i użyj kolumny. Tak, to jeszcze jedno dołączenie. I nie, ta tabela nie jest znormalizowana. Ale wciąż jest to dobry projekt dla pewnych bardzo specyficznych potrzeb.

0

Moje rozwiązanie z tydzień zaczyna się w niedzielę.

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

(tylko w celu wyjaśnienia dla przyszłych czytelników: to odpowiedź na to stare pytanie dodano powodu dobroci, że domniemanych obecna odpowiedź nie była satysfakcjonująca, więc dodałem tego rozwiązania/Definicja z dodatkowym "opcje konfiguracji" dla wszystkich sytuacji.)

Nie ma standardowej rozdzielczości do Week of month, ale ogólne rozwiązanie byłoby następujący wzór, który można konfigurować do własnych potrzeb:

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

gdzie

  • "weekday_startofweek" musi być zastąpiony przez dzień tygodnia, który ma być pierwszym dniem tygodnia (0 = Monday, 6 = Sunday).
  • "min_days_for_partial_week" to liczba dni, przez które pierwszy tydzień musi być liczony jako tydzień 1 (wartości 1 do 7). Typowe wartości to 1 (pierwszy dzień miesiąca to zawsze tydzień 1), 4 (będzie to podobne do "tygodnia tygodnia w roku", gdzie pierwszy tydzień roku jest tygodniem zawierającym czwartek, co najmniej 4 dni) i 7 (tydzień 1 to pierwszy pełny tydzień).

Ta formuła zwróci wartości 0 na 6. 0 oznacza, że ​​obecny tydzień jest częściowym tygodniu, że nie ma wystarczającej ilości dni tygodnia liczyć jako 1, a 6 może nastąpić tylko, gdy pozwalają częściowe tygodni z mniej niż 3 dni, aby być tygodnia 1.

Przykłady:

Jeśli pierwszy dzień tygodnia jest poniedziałek ("weekday_startofweek" = 0) i tydzień 1 powinno zawsze być cały tydzień ("min_days_for_partial_week" = 7), to uprości do

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

przykład dla 2016-06-02 dostaniesz 0, ponieważ czerwca 2016 rozpoczął się od Wednesda y oraz 2016-06-06 dostaniesz 1, ponieważ jest to pierwszy poniedziałek czerwca 2016

naśladować swoją formułę, gdzie pierwszy dzień tygodnia jest zawsze tygodnie 1 ("min_days_for_partial_week" = 1), a tydzień rozpoczyna się w niedzielę ("weekday_startofweek" = 6), to będzie

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

Choć może chcesz skomentować, że właściwie wiedzieć, w ciągu 2 lat, gdzie swoje stałe pochodzą.