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

Ottieni tutte le date comprese tra due date in SQL Server

Il mio primo suggerimento sarebbe utilizzare la tabella del calendario, se non ne hai una, quindi crearne una. Sono molto utili. La tua domanda è quindi semplice come:

DECLARE @MinDate DATE = '20140101',
        @MaxDate DATE = '20140106';

SELECT  Date
FROM    dbo.Calendar
WHERE   Date >= @MinDate
AND     Date < @MaxDate;

Se non vuoi o non puoi creare una tabella del calendario, puoi comunque farlo al volo senza un CTE ricorsivo:

DECLARE @MinDate DATE = '20140101',
        @MaxDate DATE = '20140106';

SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b;

Per ulteriori letture su questo vedere:

  • Genera un set o una sequenza senza loop – parte 1
  • Genera un set o una sequenza senza loop – parte 2
  • Genera un set o una sequenza senza loop – parte 3

Per quanto riguarda quindi l'utilizzo di questa sequenza di date in un cursore, ti consiglio davvero di trovare un altro modo. Di solito c'è un'alternativa basata su set che funzionerà molto meglio.

Quindi con i tuoi dati:

  date   | it_cd | qty 
24-04-14 |  i-1  | 10 
26-04-14 |  i-1  | 20

Per ottenere la quantità il 28-04-2014 (che presumo sia un tuo requisito), in realtà non hai bisogno di nessuno dei precedenti, puoi semplicemente usare:

SELECT  TOP 1 date, it_cd, qty 
FROM    T
WHERE   it_cd = 'i-1'
AND     Date <= '20140428'
ORDER BY Date DESC;

Se non lo vuoi per un articolo particolare:

SELECT  date, it_cd, qty 
FROM    (   SELECT  date, 
                    it_cd, 
                    qty, 
                    RowNumber = ROW_NUMBER() OVER(PARTITION BY ic_id 
                                                    ORDER BY date DESC)
            FROM    T
            WHERE   Date  <= '20140428'
        ) T
WHERE   RowNumber = 1;