2013-07-08 2 views
14

Vorrei elencare le date tra due date in una stored procedure di SQL Server.Come elencare tutte le date tra due date

Ad esempio:

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

Risultati:

2015-05-29 
2015-05-30 

come calcolare tutte le date tra due date?

saluti,

+0

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

risposta

14

Creare una stored procedure che fa qualcosa di simile al seguente:

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.

O meglio ancora creare una tabella di calendario e basta selezionare da quello.

+4

Penso che ogni database dovrebbe avere una tabella di calendario –

+1

Considerare l'opzione '(maxrecursion 32767)' – user443854

29

È possibile utilizzare una tabella di numeri:

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 

Risultati:

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

Non lo farei. cosa succede se non ho accesso a 'master'? –

+1

@LuisLL Questo è solo un esempio veloce di una tabella di numeri, op potrebbe utilizzare qualsiasi altro o una tabella di calendario. Solitamente è più veloce di un CTE ricorsivo (anche se mi piace usarli, so che portano problemi di prestazioni) – Lamak

+0

Ha una limitazione se è necessario ottenere un intervallo di date lungo ... come 15-20 anni. Dal momento che sta usando il parametro table..spt_values – gmsi

19

Usa questa,

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) 

passaggio del @start_date e @end_date come parametri SP.

Risultato:

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

(2 row(s) affected) 
0

È possibile creare una stored procedure di passaggio 2 date

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