sql >> Databasteknik >  >> RDS >> Sqlserver

T-SQL få antal arbetsdagar mellan 2 datum

Snälla, snälla, använd en kalendertabell. SQL Server vet ingenting om nationella helgdagar, företagsevenemang, naturkatastrofer, etc. En kalendertabell är ganska enkel att bygga, tar extremt lite utrymme och kommer att finnas i minnet om det finns tillräckligt med referenser.

Här är ett exempel som skapar en kalendertabell med 30 års datum (2000 -> 2029) men som bara kräver 200 KB på disk (136 KB om du använder sidkomprimering). Det är nästan garanterat mindre än minnesanslaget som krävs för att bearbeta någon CTE eller annan uppsättning vid körning.

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.

Nu är frågan du letar efter ganska enkel att skriva:

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

Mer information om kalendertabeller:

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

Mer information om generatoraggregat utan loopar:

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

Akta dig också för små saker som att lita på den engelska utdata av DATENAME . Jag har sett flera applikationer gå sönder eftersom vissa användare hade en annan språkinställning, och om du förlitar dig på WEEKDAY se till att du ställer in din DATEFIRST inställning på rätt sätt...



  1. [Video] Power of Indexing i PostgreSQL

  2. Laravel:Angiven nyckel var för lång; max nyckellängd är 767 byte

  3. SQL, Unika och Primära nycklar

  4. Konsolidera SQL Server-instanser genom klustring och stapling