Първото ми предложение би било да използвате вашата календарна таблица, ако нямате такава, тогава създайте такава. Те са много полезни. Тогава вашата заявка е толкова проста като:
DECLARE @MinDate DATE = '20140101',
@MaxDate DATE = '20140106';
SELECT Date
FROM dbo.Calendar
WHERE Date >= @MinDate
AND Date < @MaxDate;
Ако не искате или не можете да създадете календарна таблица, все още можете да направите това в движение без рекурсивна 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;
За повече четене по този въпрос вижте:
- Генерирайте набор или последователност без цикли – част 1
- Генерирайте набор или последователност без цикли – част 2
- Генерирайте набор или последователност без цикли – част 3
По отношение на използването на тази последователност от дати в курсора, наистина бих ви препоръчал да намерите друг начин. Обикновено има базирана на набор алтернатива, която ще работи много по-добре.
Така че с вашите данни:
date | it_cd | qty
24-04-14 | i-1 | 10
26-04-14 | i-1 | 20
За да получите количеството на 28-04-2014 (което според мен е вашето изискване), всъщност не се нуждаете от нищо от горното, можете просто да използвате:
SELECT TOP 1 date, it_cd, qty
FROM T
WHERE it_cd = 'i-1'
AND Date <= '20140428'
ORDER BY Date DESC;
Ако не го искате за конкретен артикул:
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;