2009-04-24 14 views
9

Stavo cercando una funzione semplice per ottenere la settimana del mese (anziché la settimana facile dell'anno) in una query mysql.Funzione per la settimana del mese in mysql

il meglio che potevo venire con era:

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

Mi piacerebbe sapere se sto reinventare la ruota qui, e se c'è una soluzione più semplice e più pulita?

risposta

12

AFAIK, non c'è standard la prima settimana del mese.

La prima settimana dell'anno è la settimana contenente Jan 4th.

Come si definisce la prima settimana del mese?

UPDATE:

Avrai bisogno di riscrivere la query come questa:

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

in modo che le transizioni anno vengono gestite correttamente, e le settimane iniziano Monday.

In caso contrario, la query è soddisfacente.

+0

Immagino che potrebbe non essere la soluzione più generica, ma per quello che mi serve una settimana inizia di lunedì. Quindi diciamo che il 1 ° del mese cade di domenica, quella domenica conta come la settimana 1. Se questo ha senso ... – YiSh

8

C'è un'alternativa che a volte viene utilizzata nella segnalazione di database. È per creare una tabella, chiamiamola ALMANAC, che ha una riga per data (la chiave), e ha ogni attributo necessario della data che potrebbe essere utile a fini di reporting.

In aggiunta alla colonna della settimana del mese, potrebbe esserci una colonna per indicare se la data è o meno una festività aziendale e cose del genere. Se la tua azienda ha un anno fiscale che inizia a luglio o qualche altro mese, puoi includere l'anno fiscale, il mese fiscale, la settimana fiscale ecc. A cui appartiene ogni data.

Quindi si scrive un programma per popolare questo tavolo dal nulla, dato un intervallo di date da popolare. Si includono tutti i calcoli del calendario pazzo solo una volta in questo programma.

Quindi, quando è necessario conoscere l'attributo per una data in un'altra tabella, basta fare un join e utilizzare la colonna. Sì, è un altro join. E no, questo tavolo non è normalizzato. Ma è ancora un buon design per certi bisogni molto specifici.

0

La mia soluzione con una settimana inizia di domenica.

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

(Giusto per chiarire per i lettori futuri: questa risposta a questa vecchia domanda è stato aggiunto a causa di una taglia che implicava la risposta attuale non era soddisfacente, così ho aggiunto questa soluzione/definizione con l'aggiunta di "opzioni di configurazione" per tutti i tipi di situazioni.)

Non esiste una definizione standard per la Week of month, ma una soluzione generale sarebbe la seguente formula, che si può configurare per le vostre esigenze:

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

dove

  • "weekday_startofweek" deve essere sostituito dal giorno della settimana che si desidera essere il primo giorno della settimana (0 = Monday, 6 = Sunday).
  • "min_days_for_partial_week" è il numero di giorni che la prima settimana deve contare come settimana 1 (valori 1 a 7). I valori comuni saranno 1 (il primo giorno del mese è sempre la settimana 1), 4 (questo sarebbe simile alla "settimana iso dell'anno", dove la prima settimana dell'anno è la settimana che contiene il giovedì, così almeno 4 giorni) e 7 (la settimana 1 è la prima settimana completa).

Questa formula restituirà i valori 0 a 6. 0 significa che la settimana in corso è una settimana parziale, che non hanno abbastanza giorni per contano come 1 settimana, e 6 può accadere solo quando si consente settimane parziali con meno di 3 giorni per essere settimana 1.

Esempi:

Se il primo giorno della settimana è Lunedi ("weekday_startofweek" = 0) e la settimana 1 deve essere sempre una settimana intera ("min_days_for_partial_week" = 7), questo semplificherà al

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

ad esempio, per 2016-06-02 si otterrà 0, perché giugno Il 2016 è iniziato con un Wednesda y e per 2016-06-06 otterrete 1, poiché questo è il primo Lunedi nel mese di giugno 2016.

Per emulare la formula, dove il primo giorno della settimana è sempre settimana 1 ("min_days_for_partial_week" = 1), e la settimana inizia con la Domenica ("weekday_startofweek" = 6), questo sarà

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

Anche se si potrebbe desiderare di commentare che correttamente per comunicare in 2 anni in cui i vostri costanti provenienza.

Problemi correlati