Overblog Folge diesem Blog
Edit post Administration Create my blog
Blog von Olaf Helper

Einfache Datenreihen erzeugen

14. Oktober 2009 , Geschrieben von Olaf Helper Veröffentlicht in #T-SQL

Für manche Aufgabenstellungen benötigt man Datenreihen, z.B. fortlaufende Nummern oder alle Tage eines Jahres, um zu überprüfen, ob den für alle Tage auch Daten vorhanden sind.

Natürlich kann man so etwas auch prüfen, indem man die Differenz zum höchsten Vorgänger bildet; die darf dann nicht größer als 1 sein.

Einfacher geht es, wenn man eine Tabelle hat, die alle Werte beinhaltet. Jetzt könnte man eine (temporär) anlegen, sie über eine Schleife befüllen und die dann verwenden. Bei größeren Datenmengen ist das auch zu empfehlen, da man zur Verbesserung der Performanz einen Index anlegen kann.

Wenn man aber nur mal eben alle 365 Tage eines Jahres benötigt, lohnt sich der Aufwand nicht, das geht auch einfach:  Mittels einer rekursiven CTE (Common Table Expression). Das funktioniert wie folgt:

Ausgangspunkt ist eine CTE mit einem SELECT von den statischen Startdaten (Nr 1 / 01.Jan, etc). Das verbindet man mittels UNION mit einer Selektion der CTE (= Rekursion), wobei die Werte um 1 erhöht werden. Die Anzahl der Rekursionen schränkt man über eine WHERE Klausel auf echt-kleiner der Maximal-Werte ein. Echt-kleiner wird verwendet, da ja das (letzte) Ergebnis mit +1 zurück geliefert wird.

Das war es schon, keine große Zauberei.

 

Es gibt nur die „kleine“ Einschränkung auf maximal 32.747 Rekursionen; aber die Lösung ist wie schon erwähnt eh für kleinere Datenreihen gedacht.

 

 WITH [loops] (Sequence, EveryDayOfYear) AS 
  (SELECT 1 AS Sequence 
  ,CONVERT(datetime, '20090101', 112) AS EveryDayOfYear 
  UNION ALL 
  SELECT Sequence + 1 AS Sequence 
  ,DATEADD(d, 1, EveryDayOfYear) AS EveryDayOfYear 
  FROM [loops] 
  WHERE EveryDayOfYear < CONVERT(datetime, '20091231', 112)) 
 SELECT Sequence 
  ,EveryDayOfYear 
  ,CASE WHEN DATEPART(dw, EveryDayOfYear) < 6  
  THEN 'Werktag' 
  ELSE 'Wochenende'  
  END AS IsWeekEnd  
 FROM [loops] 
 OPTION (MAXRECURSION 366); 

 

Ergebnis:

 

Sequence

EveryDayOfYear

IsWeekEnd

1

2009-01-01 00:00:00.000

Werktag

2

2009-01-02 00:00:00.000

Werktag

3

2009-01-03 00:00:00.000

Wochenende

4

2009-01-04 00:00:00.000

Wochenende

5

2009-01-05 00:00:00.000

Werktag

6

2009-01-06 00:00:00.000

Werktag

7

2009-01-07 00:00:00.000

Werktag

359

2009-12-25 00:00:00.000

Werktag

360

2009-12-26 00:00:00.000

Wochenende

361

2009-12-27 00:00:00.000

Wochenende

362

2009-12-28 00:00:00.000

Werktag

363

2009-12-29 00:00:00.000

Werktag

Diesen Post teilen

Repost 0

Kommentiere diesen Post