Ma première suggestion serait d'utiliser votre table de calendrier, si vous n'en avez pas, créez-en une. Ils sont très utiles. Votre requête est alors aussi simple que :
DECLARE @MinDate DATE = '20140101',
@MaxDate DATE = '20140106';
SELECT Date
FROM dbo.Calendar
WHERE Date >= @MinDate
AND Date < @MaxDate;
Si vous ne voulez pas ou ne pouvez pas créer de tableau de calendrier, vous pouvez toujours le faire à la volée sans CTE récursif :
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;
Pour en savoir plus à ce sujet, consultez :
- Générer un ensemble ou une séquence sans boucles – partie 1
- Générer un ensemble ou une séquence sans boucles – partie 2
- Générer un ensemble ou une séquence sans boucles – partie 3
En ce qui concerne l'utilisation de cette séquence de dates dans un curseur, je vous recommanderais vraiment de trouver un autre moyen. Il existe généralement une alternative basée sur un ensemble qui fonctionnera beaucoup mieux.
Alors avec vos données :
date | it_cd | qty
24-04-14 | i-1 | 10
26-04-14 | i-1 | 20
Pour obtenir la quantité le 28-04-2014 (ce que je suppose est votre exigence), vous n'avez en fait besoin d'aucun des éléments ci-dessus, vous pouvez simplement utiliser :
SELECT TOP 1 date, it_cd, qty
FROM T
WHERE it_cd = 'i-1'
AND Date <= '20140428'
ORDER BY Date DESC;
Si vous ne le souhaitez pas pour un article en particulier :
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;