2013-07-08 18 views
14

Ich möchte Termine zwischen zwei Datumsangaben in einer gespeicherten SQL Server-Prozedur auflisten.So listen Sie alle Daten zwischen zwei Daten auf

Zum Beispiel:

Date1: 2015-05-28 
Date2: 2015-05-31 

Ergebnisse:

2015-05-29 
2015-05-30 

Wie alle Termine zwischen zwei angegebenen Daten berechnen?

Grüße,

+0

erstellen http://www.sqlperformance.com/2013/01/t-sql-queries/ generate-a-set-3 –

Antwort

14

eine gespeicherte Prozedur erstellen, die in etwa wie folgt funktioniert:

declare @startDate date; 
declare @endDate date; 

select @startDate = '20150528'; 
select @endDate = '20150531'; 

with dateRange as 
(
    select dt = dateadd(dd, 1, @startDate) 
    where dateadd(dd, 1, @startDate) < @endDate 
    union all 
    select dateadd(dd, 1, dt) 
    from dateRange 
    where dateadd(dd, 1, dt) < @endDate 
) 
select * 
from dateRange 

SQL Fiddle with demo.

Oder noch besser erstellen Sie eine Kalender-Tabelle und wählen Sie einfach aus.

+4

Ich denke, dass jede Datenbank eine Kalender-Tabelle haben sollte –

+1

Betrachten Sie Option (maxrecursion 32767) ' – user443854

29

Sie können eine Zahlen-Tabelle verwenden:

DECLARE @Date1 DATE, @Date2 DATE 
SET @Date1 = '20150528' 
SET @Date2 = '20150531' 

SELECT DATEADD(DAY,number+1,@Date1) [Date] 
FROM master..spt_values 
WHERE type = 'P' 
AND DATEADD(DAY,number+1,@Date1) < @Date2 

Ergebnisse:

╔════════════╗ 
║ Date ║ 
╠════════════╣ 
║ 2015-05-29 ║ 
║ 2015-05-30 ║ 
╚════════════╝ 
+2

Ich würde das nicht tun. Was passiert, wenn ich keinen Zugriff auf "Master" habe? –

+1

@LuisLL Das ist nur ein kurzes Beispiel für eine Zahlentabelle, op könnte eine andere oder eine Kalendertabelle verwenden. Es ist in der Regel schneller als eine rekursive CTE (obwohl ich sie gerne verwende, weiß ich, dass sie Performance-Probleme bringen) – Lamak

+0

Hat Einschränkung, wenn Sie einen langen Datumsbereich benötigen ... wie 15-20 Jahre. Da es Tabellenmaster..spt_values ​​verwendet – gmsi

19

Verwendung,

DECLARE @start_date DATETIME = '2015-02-12 00:00:00.000'; 
DECLARE @end_date DATETIME = '2015-02-13 00:00:00.000'; 

WITH AllDays 
      AS (SELECT @start_date AS [Date], 1 AS [level] 
       UNION ALL 
       SELECT DATEADD(DAY, 1, [Date]), [level] + 1 
       FROM  AllDays 
       WHERE [Date] < @end_date) 
    SELECT [Date], [level] 
    FROM AllDays OPTION (MAXRECURSION 0) 

passieren die @start_date und @end_date als SP-Parameter.

Ergebnis:

Date     level 
----------------------- ----------- 
2015-02-12 00:00:00.000 1 
2015-02-13 00:00:00.000 2 

(2 row(s) affected) 
0

Sie können eine gespeicherte Prozedur übergeben 2 Termine

CREATE PROCEDURE SELECTALLDATES 
(
@StartDate as date, 
@EndDate as date 
) 
AS 
Declare @Current as date = DATEADD(DD, 1, @BeginDate); 

Create table #tmpDates 
(displayDate date) 

WHILE @Current < @EndDate 
BEGIN 
insert into #tmpDates 
VALUES(@Current); 
set @Current = DATEADD(DD, 1, @Current) -- add 1 to current day 
END 

Select * 
from #tmpDates 

drop table #tmpDates