Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

T-SQL ottiene il numero di giorni lavorativi tra 2 date

Per favore, per favore, per favore, usa una tabella del calendario. SQL Server non sa nulla di festività nazionali, eventi aziendali, disastri naturali e così via. Una tabella di calendario è abbastanza facile da creare, occupa una quantità estremamente ridotta di spazio e sarà in memoria se viene citata a sufficienza.

Ecco un esempio che crea una tabella calendario con 30 anni di date (2000 -> 2029) ma richiede solo 200 KB su disco (136 KB se usi la compressione della pagina). È quasi garantito che sia inferiore alla concessione di memoria richiesta per elaborare alcuni CTE o altri set in fase di esecuzione.

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.

Ora la query che stai cercando è abbastanza semplice da scrivere:

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

Maggiori informazioni sui tavoli del calendario:

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

Maggiori informazioni sui gruppi elettrogeni senza loop:

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

Fai attenzione anche a piccole cose come fare affidamento sull'output inglese di DATENAME . Ho visto diverse applicazioni interrompersi perché alcuni utenti avevano un'impostazione della lingua diversa e se fai affidamento su WEEKDAY assicurati di impostare il tuo DATEFIRST impostazione appropriata...