Sunday, 29. march 2009 7 29 /03 /März /2009 14:44

Im Bereich der Waren-, Lagerwirtschaft und Disposition arbeitet man in der Regel eher mit der Kalenderwoche statt mit einem fixen Datum; natürlich bevorzugt im der Kalenderwoche nach ISO Norm.

Bis einschließlich dem Microsoft SQL Server 2005 gab es kein Bordmittel zum Umrechnen in die ISO-KW, man fand aber in der BOL unter dem Thema CREATE FUNCTION (Transact-SQL)“ im Beispiel A. ein Script für eine benutzerdefinierte Funktion „ISOWeek“, mit der man umrechnen kann.

Im MS SQL Server 2008 hat die ISO Woche nun auch im Standard Einzug gehalten mit dem Parameter ISO_WEEK / ISOWK / ISOWW für die Funktion DATEPART:


SELECT
DATEPART(ISOWK,
                CAST('20060101' AS datetime)) AS IsoWeek


Was mich aber an den Funktionen stört, ist das das Jahr nicht mitgeliefert bzw. das ich bei dem Beispiel mit dem 2006-01-01 darauf achten muss, das die resultierende KW 52 ins Jahr 2005 fällt, nicht in 2006.

Ich habe mir deshalb auf Basis der ISOWeek Funktion eine eigene erstellt, die es mir im Format YYYYWW als Integer zurückliefert. Das auf splitten in ein separates Jahr / Woche ist dann leicht.

SELECT dbo.fnDate2ISOYearWeek(GetDate()) / 100 AS Jahr,
       dbo.fnDate2ISOYearWeek(GetDate()) % 100 AS Woche 


Hier das Anlage-Script für die Funktion
fnDate2ISOYearWeek


-- Alte Version ggf. DROPen
IF OBJECT_ID (N'dbo.fnDate2ISOYearWeek', N'FN') IS NOT NULL
    DROP FUNCTION dbo.fnDate2ISOYearWeek;
GO
 
CREATE FUNCTION dbo.fnDate2ISOYearWeek(@Date datetime)
       RETURNS int
AS
-- fnDate2ISOYearWeek - Stand 23.03.2009
-- Liefert zu einem Datum die Kalenderwoche und -Jahr
-- nach ISO im Format YYYYWW als Integer 
BEGIN
    DECLARE @ISOweek smallint,
            @ISOYear int;    
    SET @ISOYear = DATEPART(yy, @Date);
    SET @ISOweek = DATEPART(wk, @DATE) + 1
                   - DATEPART(wk, CAST(@ISOYear as CHAR(4)) + '0104');
      
     -- Sonderfall: Erste KW <> 4 Tage
    IF (@ISOweek = 0) 
    BEGIN
        SET @ISOYear = @ISOYear - 1;
        SET @ISOweek = DATEPART(wk, CAST(@ISOYear AS CHAR(4))
                                    + '12' 
                                    + CAST(24 + DATEPART(DAY, @DATE) AS CHAR(2))
                                ) + 1
                       - DATEPART(wk, CAST(@ISOYear as CHAR(4)) + '0104')
                       + 1;
    END;
  
    --Sonderfall: Letzte 3 Tage falen in erste KW Folgejahr
    IF DATEPART(mm, @DATE) = 12 
       AND DATEPART(dd, @DATE) - DATEPART(dw, @DATE) >= 28
    BEGIN
        SET @ISOweek = 1;
        SET @ISOYear = @ISOYear + 1;
    END;
    
    RETURN(@ISOYear * 100 + @ISOweek);
END;
GO
 
-- Unit-Test mit Sonder- und Normalfällen
SELECT Datum, DATENAME(dw, Datum) AS WochenTag,
       DATENAME(isowk, Datum) AS InternalIsoWeek, 
       dbo.ISOweek(Datum) AS MSIsoWeek,
       dbo.fnDate2ISOYearWeek(Datum) AS myIsoYearWeek
FROM (SELECT CAST('20060101' as datetime) AS DATUM UNION
      SELECT CAST('20060102' as datetime) AS DATUM UNION
      SELECT CAST('20061231' as datetime) AS DATUM UNION
      SELECT CAST('20050101' as datetime) AS DATUM UNION
      SELECT CAST('20050102' as datetime) AS DATUM UNION
      SELECT CAST('20050103' as datetime) AS DATUM 
      ) AS DatumsQuelle
ORDER BY DATUM
von Olaf Helper - veröffentlicht in: T-SQL - Community: SQL Scripter
Kommentar hinzufügen - Kommentare (2)ansehen
Zurück zur Startseite

Kommentare

Funktioniert leider nicht korrekt. Beispiel:
31.12.2009 und 01.01.2010 beide Tage fallen in KW 53/2009. die Funktion liefert aber KW 52 und KW 53.
Kommentarnr1 gepostet von Flugs am 10.12.2010 um 11h57

Hallo,

die Funktion funktioniert einwandfrei. Wenn Du Dich etwas mit dem Thema beschäftigst wird Du feststellen, dass das Ergebnis natürlich von den User Setting abhängt, genauer von SET DateFirst, also an welchem Tag den die Woche beginnt und somit auch wann die erste ISO Woche ist.

Antwort von Olaf Helper am 15.02.2011 um 20h03
Hallo,
diese selbstgebaute Funktion funktioniert auf den ersten Anhieb ziemlich gut, nur der Versuch die Ergebnisse nach dieser Spalte zu gruppieren läuft gegen die Pumpe (GROUP BY) ist für mich so spontan nicht gut nach zu voll ziehen.
Kommentarnr2 gepostet von CH am 27.01.2012 um 11h48

Über diesen Blog

Kategorien

Kalender

June 2012
M T W T F S S
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
<< < > >>

Syndication (RSS)

  • RSS-Feed der Artikel

Suchen

Blog erstellen

Erstellen Sie einen Blog auf OverBlog - Kontakt - Nutzungsbedingungen - Werbung - Missbrauch melden - Impressum - Artikel mit den meisten Kommentaren