Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

T-SQL erhält die Anzahl der Arbeitstage zwischen 2 Daten

Bitte, bitte, bitte verwenden Sie eine Kalendertabelle. SQL Server weiß nichts über nationale Feiertage, Firmenveranstaltungen, Naturkatastrophen usw. Eine Kalendertabelle ist ziemlich einfach zu erstellen, nimmt extrem wenig Platz ein und bleibt im Speicher, wenn genügend darauf verwiesen wird.

Hier ist ein Beispiel, das eine Kalendertabelle mit Datumswerten von 30 Jahren (2000 -> 2029) erstellt, aber nur 200 KB auf der Festplatte benötigt (136 KB, wenn Sie die Seitenkomprimierung verwenden). Das ist fast garantiert weniger als die Speicherzuteilung, die erforderlich ist, um einen CTE oder einen anderen Satz zur Laufzeit zu verarbeiten.

CREATE TABLE dbo.Calendar
(
  dt DATE PRIMARY KEY, -- use SMALLDATETIME if < SQL Server 2008
  IsWorkDay BIT
);

DECLARE @s DATE, @e DATE;
SELECT @s = '2000-01-01' , @e = '2029-12-31';

INSERT dbo.Calendar(dt, IsWorkDay)
  SELECT DATEADD(DAY, n-1, '2000-01-01'), 1 
  FROM
  (
    SELECT TOP (DATEDIFF(DAY, @s, @e)+1) ROW_NUMBER() 
      OVER (ORDER BY s1.[object_id])
      FROM sys.all_objects AS s1
      CROSS JOIN sys.all_objects AS s2
  ) AS x(n);

SET DATEFIRST 1;

-- weekends
UPDATE dbo.Calendar SET IsWorkDay = 0 
  WHERE DATEPART(WEEKDAY, dt) IN (6,7);

-- Christmas
UPDATE dbo.Calendar SET IsWorkDay = 0 
  WHERE MONTH(dt) = 12
  AND DAY(dt) = 25
  AND IsWorkDay = 1;

-- continue with other holidays, known company events, etc.

Jetzt ist die Abfrage, nach der Sie suchen, ganz einfach zu schreiben:

SELECT COUNT(*) FROM dbo.Calendar
  WHERE dt >= '20130110'
    AND dt <  '20130115'
    AND IsWorkDay = 1;

Weitere Informationen zu Kalendertabellen:

http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html

Weitere Informationen zu Stromerzeugern ohne Schleifen:

http://www.sqlperformance.com/tag/date-ranges

Hüten Sie sich auch vor Kleinigkeiten wie dem Verlassen auf die englische Ausgabe von DATENAME . Ich habe gesehen, dass mehrere Anwendungen unterbrochen wurden, weil einige Benutzer eine andere Spracheinstellung hatten und wenn Sie sich auf WEEKDAY verlassen Stellen Sie sicher, dass Sie Ihr DATEFIRST festlegen richtig einstellen...