Jag hade ett liknande problem:Jag behövde beräkna veckonummer baserat på följande regler:
- Veckan börjar på fredag
- De återstående dagarna av ett år (alla dagar efter årets sista fredag som inte avslutar en vecka) ska räknas in i den första veckan på nästa år.
Till exempel:
- 27/12/2012 (torsdag) bör vara vecka 52 2012
- 28/12/2012 (fredag) bör vara vecka 1 2013
- Vecka 1 2013 går från 28/12/2012 till 3/1/2013
Jag gjorde detta påstående som beräknar både ÅR och VECKANUMMER baserat på dessa regler som du enkelt kan anpassa till din situation:
SELECT IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, YEAR(current_date)+1, YEAR(current_date)),
IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, 1, ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7));
Den knepiga delen är bara detta uttryck:
ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7)
Resten (If-satser) är bara för att anpassa resultatet av uttrycket för att göra år+1 och vecka =1 i vecka 53.
Jag ska försöka förklara uttrycket så gott jag kan. Följande uttryck ger dig veckonummer rent enkelt (dagen på året dividerat med 7 dagar i veckan avrundat):
ceil(( dayofyear(current_date))/7)
Men nu vill du få det att börja på fredag (eller någon annan dag). För att göra detta måste du lägga till den aktuella dagen, dagarna i den första veckan som var en del av föregående år (det är som att din nuvarande faktiskt började några dagar innan, eftersom din första vecka innehåller dagar från föregående år). expression beräknar denna offset baserat på veckodagen den 1 januari:
dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET
Offseten är skillnaden mellan 7 och det veckodagnummer du vill att veckan ska börja:
- 0 för lördag
- 1 för fredag
- 2 för torsdag
- 3 för onsdag...
Så nu behöver du bara lägga till det till det föregående vilket resulterar i det ovan nämnda uttrycket som beräknar veckotalen som börjar på vilken veckodag som helst och antar att vecka 1 börjar på föregående år:
ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET )/7)
Sedan lade jag bara till en OM som gör vecka 53 till vecka 1 och en annan för att lägga till 1 till året om det är vecka 53.