Mitt första förslag skulle vara att använda din kalendertabell, om du inte har en, skapa en. De är mycket användbara. Din fråga är då så enkel som:
DECLARE @MinDate DATE = '20140101',
@MaxDate DATE = '20140106';
SELECT Date
FROM dbo.Calendar
WHERE Date >= @MinDate
AND Date < @MaxDate;
Om du inte vill eller inte kan skapa en kalendertabell kan du fortfarande göra detta i farten utan en rekursiv 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;
För ytterligare läsning om detta, se:
- Generera en uppsättning eller sekvens utan loopar – del 1
- Generera en uppsättning eller sekvens utan loopar – del 2
- Generera en uppsättning eller sekvens utan loopar – del 3
När det gäller att sedan använda denna sekvens av datum i en markör, skulle jag verkligen rekommendera dig att hitta ett annat sätt. Det finns vanligtvis ett set baserat alternativ som kommer att fungera mycket bättre.
Så med dina uppgifter:
date | it_cd | qty
24-04-14 | i-1 | 10
26-04-14 | i-1 | 20
För att få kvantiteten den 28-04-2014 (som jag förstår är ditt krav), behöver du faktiskt inte något av ovanstående, du kan helt enkelt använda:
SELECT TOP 1 date, it_cd, qty
FROM T
WHERE it_cd = 'i-1'
AND Date <= '20140428'
ORDER BY Date DESC;
Om du inte vill ha det för ett visst föremål:
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;