Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Obter todas as datas entre duas datas no SQL Server


Minha primeira sugestão seria usar sua tabela de calendário, se você não tiver uma, crie uma. Eles são muito úteis. Sua consulta é então tão simples quanto:
DECLARE @MinDate DATE = '20140101',
        @MaxDate DATE = '20140106';

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

Se você não quiser ou não puder criar uma tabela de calendário, ainda poderá fazer isso rapidamente sem um CTE recursivo:
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;

Para ler mais sobre isso, veja:
  • Gerar um conjunto ou sequência sem loops – parte 1
  • Gerar um conjunto ou sequência sem loops – parte 2
  • Gerar um conjunto ou sequência sem loops – parte 3

Com relação a usar essa sequência de datas em um cursor, eu realmente recomendo que você encontre outra maneira. Geralmente, há uma alternativa baseada em conjunto que terá um desempenho muito melhor.

Então com seus dados:
  date   | it_cd | qty 
24-04-14 |  i-1  | 10 
26-04-14 |  i-1  | 20

Para obter a quantidade em 28-04-2014 (que eu entendo ser sua exigência), você realmente não precisa de nenhum dos itens acima, você pode simplesmente usar:
SELECT  TOP 1 date, it_cd, qty 
FROM    T
WHERE   it_cd = 'i-1'
AND     Date <= '20140428'
ORDER BY Date DESC;

Se você não quiser para um item específico:
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;