Hej Tyvärr är det helt enkelt så Microsoft valt att implementera det i SQL Server. Förste januari räknas alltid som vecka 1 i SQL Server, och vecka 2 börjar då den första söndagen (eller annan veckodag om man ändrat datefirst inställning) på året inträffar. Detta är alltså inte hur ISO-standarden - som vi i Sverige följer - ser ut. Om man använder sql server 2000 så kan man gå runt problemet genom att skriva en UDF som tar emot ett datum och returnerar rätt veckonummer. OK, Tack båda två för svar. Sådärja, då har man haft en helg och lite tid på sig att ge ett ordentligt svar på detta problem. Nedanstående kod kan användas för att beräkna ISO veckonummer, dvs enligt den standard vi följer i Sverige, för ett specifikt datum. I detta fallet är det en [tabell] med en kolumn [datumkolumn] som man beräknar iso-vecka för. Fungerar på alla versioner av SQL Server och använder inte nån prestanda-krävande udf. Jag har testat den mot den tabell jag har med datum och veckonummer i (alla dagar från 1990 och 50 år framåt) och veckonummer stämmer överens för alla datum. Bra! Perfekt. Har själv suttit och jämfört ett antal datum med kalendrar och det ser korrekt ut ja. Prestandamässigt använde den ungefär 1/10 CPU jämfört med en UDF, så den fungerar bra att köra också. Har skrivit lite mer om den: http://thinkdo.org/blogs/chris/archive/2004/12/20/151.aspx Jag har inte tittat närmare på koden, men tror du att den går att förkorta? Man vill ju inte gärna ha så mycket extrakod i 20 procedurer... Nej, inte utan att ändra till att t ex lägga in funktionaliteten i en UDF, men då blir det prestandamässigt oerhört sämre eftersom det inte är set-based. Är det för enbart ett datum (i motsats till X rader i en tabell) så kan du naturligtvis anropa en udf eller lagrad procedur som beräknar för det datumet. Sen kan man ju alltid fråga sig om det är en funktion för databasen överhuvudtaget. Kanske ska du bara returnera datumet och låta applikationen som hämtar det avgöra hur veckonummer ska beräknas.Veckor i SQL Server
Är det någon som vet varför SQL server tolkar vecka 53 som vecka 1?
Och hur kommer man runt det?
Hälsningar
Mikael AnderssonSv: Veckor i SQL Server
Ett sätt att komma runt det är att skapa en egen tabell med kalenderinformation, t ex ISO-veckonummer för varje datum.Sv:Veckor i SQL Server
Microsofts hantering av veckonummer är en gammal goding. De har nog aldrig lyckats med en korrekt implementering, och de verkar inte bry sig om att fixa sina gamla fel heller (t.ex. veckonummerfelet i vb6 kvarstår efter 6 år och ett antal uppdateringar)...
/PelleSv: Veckor i SQL Server
Vi får väl hitta på något klurigt.
God Jul
MickeSv:Veckor i SQL Server
<code>
SELECT [datumkolumn], CASE
-- Specialfall där datumet ingår i vecka 52 (eller 53) för föregående år
WHEN [datumkolumn] < CASE (DATEPART(dw, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04') + @@DATEFIRST - 1) % 7
WHEN 1 THEN CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04'
WHEN 2 THEN DATEADD(d, -1, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 3 THEN DATEADD(d, -2, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 4 THEN DATEADD(d, -3, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 5 THEN DATEADD(d, -4, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 6 THEN DATEADD(d, -5, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
ELSE DATEADD(d, -6, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
END
THEN
-- Räkna ut veckonummer för dagar som ingår i överlappande vecka 52 eller 53
(DATEDIFF(d,
CASE (DATEPART(dw, CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04') + @@DATEFIRST - 1) % 7
WHEN 1 THEN CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04'
WHEN 2 THEN DATEADD(d, -1, CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04')
WHEN 3 THEN DATEADD(d, -2, CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04')
WHEN 4 THEN DATEADD(d, -3, CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04')
WHEN 5 THEN DATEADD(d, -4, CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04')
WHEN 6 THEN DATEADD(d, -5, CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04')
ELSE DATEADD(d, -6, CAST(YEAR([datumkolumn]) - 1 AS CHAR(4)) + '-01-04')
END,
[datumkolumn]
) / 7) + 1
-- Specialfall där datumet ingår i vecka 1 för kommande år
WHEN [datumkolumn] >= CASE (DATEPART(dw, CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04') + @@DATEFIRST - 1) % 7
WHEN 1 THEN CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04'
WHEN 2 THEN DATEADD(d, -1, CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04')
WHEN 3 THEN DATEADD(d, -2, CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04')
WHEN 4 THEN DATEADD(d, -3, CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04')
WHEN 5 THEN DATEADD(d, -4, CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04')
WHEN 6 THEN DATEADD(d, -5, CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04')
ELSE DATEADD(d, -6, CAST(YEAR([datumkolumn]) + 1 AS CHAR(4)) + '-01-04')
END
THEN 1 -- Alltid vecka 1 förstås
ELSE
-- Räkna ut veckonummer för alla dagar som ej är specialfall ovan
(DATEDIFF(d,
CASE (DATEPART(dw, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04') + @@DATEFIRST - 1) % 7
WHEN 1 THEN CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04'
WHEN 2 THEN DATEADD(d, -1, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 3 THEN DATEADD(d, -2, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 4 THEN DATEADD(d, -3, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 5 THEN DATEADD(d, -4, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
WHEN 6 THEN DATEADD(d, -5, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
ELSE DATEADD(d, -6, CAST(YEAR([datumkolumn]) AS CHAR(4)) + '-01-04')
END,
[datumkolumn]
) / 7) + 1
END
AS IsoWeek
FROM [tabell]
</code>
Om någon vill kontrollera detta och rapportera eventuella fel här vore jag glad. Jag har själv kontrollerat ganska ordentligt, men det skadar ju inte med fler ögon.Sv: Veckor i SQL Server
/PelleSv:Veckor i SQL Server
Sv: Veckor i SQL Server
Sv:Veckor i SQL Server