Moją pierwszą sugestią byłoby użycie tabeli kalendarza, jeśli jej nie masz, utwórz ją. Są bardzo przydatne. Twoje zapytanie jest wtedy tak proste, jak:
DECLARE @MinDate DATE = '20140101',
@MaxDate DATE = '20140106';
SELECT Date
FROM dbo.Calendar
WHERE Date >= @MinDate
AND Date < @MaxDate;
Jeśli nie chcesz lub nie możesz utworzyć tabeli kalendarza, możesz to zrobić w locie bez rekurencyjnego CTE:
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;
Aby uzyskać więcej informacji na ten temat, zobacz:
- Generuj zestaw lub sekwencję bez pętli – część 1
- Generuj zestaw lub sekwencję bez pętli – część 2
- Generuj zestaw lub sekwencję bez pętli – część 3
Jeśli chodzi o użycie tej sekwencji dat w kursorze, naprawdę polecam znaleźć inny sposób. Zwykle istnieje alternatywa oparta na zestawie, która będzie działać znacznie lepiej.
Więc z Twoimi danymi:
date | it_cd | qty
24-04-14 | i-1 | 10
26-04-14 | i-1 | 20
Aby uzyskać ilość w dniu 28-04-2014 (która, jak sądzę, jest twoim wymaganiem), w rzeczywistości nie potrzebujesz żadnego z powyższych, możesz po prostu użyć:
SELECT TOP 1 date, it_cd, qty
FROM T
WHERE it_cd = 'i-1'
AND Date <= '20140428'
ORDER BY Date DESC;
Jeśli nie chcesz tego dla konkretnego przedmiotu:
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;