2009-09-29 16 views
2

Utilisation d'un serveur SQL 2000. Si la date de début est 06/23/2008 et la date de fin est 06/30/2008Comment afficher toutes les dates entre deux dates données dans SQL

Puis-je besoin de la sortie de la requête comme

06/23/2008 
06/24/2008 
06/25/2008 
. 
. 
. 
06/30/2008 

Je créé un nom de table comme nombre entier qui a une colonne, les valeurs de la colonne sont 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 j'utilisé le dessous mentionné requête

essayé Query

SELECT DATEADD(d, H.i * 100 + T .i * 10 + U.i, '" & dtpfrom.Value & "') AS Dates 
    FROM integers H 
CROSS JOIN integers T 
CROSS JOIN integers U 
order by dates 

La requête ci-dessus n'affiche que 999 dates. 999 Dates signifie (365 + 365 + 269) Dates uniquement. Supposons que je souhaite sélectionner plus de 3 ans (du 01/01/2003 au 01/01/2008). La requête ci-dessus ne devrait pas convenir.

Comment modifier ma requête? Ou toute autre requête est disponible pour la condition ci-dessus.

S'il vous plaît veuillez me fournir la requête.

Répondre

0

Cela vous obtenez jusqu'à 100.000 jours:

SELECT DATEADD(d, Y.i * 10000 + X.i * 1000 + H.i * 100 + T .i * 10 + U.i, '" & dtpfrom.Value & "') AS Dates 
FROM integers H 
CROSS JOIN integers T 
CROSS JOIN integers U 
CROSS JOIN integers X 
CROSS JOIN integers Y 
order by dates 
3

Une façon possible (ne dis pas que c'est le meilleur ou le plus efficace) serait quelque chose comme ceci:

DECLARE @StartDate DATETIME 
SET @StartDate = '06/23/2008' 

DECLARE @EndDate DATETIME 
SET @EndDate = '06/30/2008' 

DECLARE @TableOfDates TABLE(DateValue DATETIME) 

DECLARE @CurrentDate DATETIME 

SET @CurrentDate = @startDate 

WHILE @CurrentDate <= @endDate 
BEGIN 
    INSERT INTO @TableOfDates(DateValue) VALUES (@CurrentDate) 

    SET @CurrentDate = DATEADD(DAY, 1, @CurrentDate) 
END 

SELECT * FROM @TableOfDates 

Cela fonctionne avec un certain nombre de dates, une plage de dates, et n'a pas besoin d'un table "helper" spécifique avec des valeurs entières.

Il stocke toutes les dates pertinentes dans une variable de table en mémoire, ce qui vous permet de l'utiliser par ex. une autre instruction SELECT ou tout ce dont vous avez besoin pour.

Marc

+0

Ceci est l'approche idéale pour pré-2005 parce que vous ne pouvez pas utiliser CTE - voir les commentaires dans cette question pour plus de détails: http://stackoverflow.com/questions/1478951/tsql-generate-a-resultset-of -incrementing-dates/1479028 # 1479028 –

+0

Cette boucle sera beaucoup plus lente que l'utilisation d'une table Numbers traditionnelle, comme décrit dans ma réponse. Si c'est une chose unique, ce serait OK à utiliser. Toutefois, si vous générez plusieurs plages de dates, utilisez une méthode sans boucle plus efficace. –

+0

Oui - mais vous n'avez pas besoin d'une table de nombres supplémentaires! Et pour jsut 10 ou 20 lignes, je ne sais pas à quel point la différence sera. –

2

Voir:

Why should I consider using an auxiliary calendar table?

Une table de calendrier peut faire beaucoup plus facile de développer des solutions autour de tout modèle d'entreprise qui implique des dates. Dernière fois que j'ai vérifié, cela englobe à peu près tous les modèles d'affaires que vous pouvez penser, dans une certaine mesure. Constant problèmes qui finissent par exiger verbeux, complexes et inefficaces méthodes comprennent les questions suivantes:

  • Combien de jours ouvrables entre x et y?
  • ...
+0

Ceci est une technique d'entreposage de données, et est très puissant comme vous le dites. Il doit encore être peuplé, cependant. – Hooloovoo

4

Je ne boucle pour créer une liste de dates, utilisez une table Numbers (pas seulement un table de valeurs 0 à 9), ils sont utiles pour beaucoup de choses: http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-numbers-table.html Avec une vraie table Numbers vous n'avez pas besoin de CROSS JOIN plusieurs fois et de rendre la requête trop complexe.

Pour que cette méthode fonctionne, vous devez faire une configuration horaire:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number 
    INTO Numbers 
    FROM sys.columns s1 
    CROSS JOIN sys.columns s2 
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number) 

Une fois la table des numéros est configuré, utilisez cette requête:

SELECT 
    @Start+Number-1 
    FROM Numbers 
    WHERE Number<=DATEDIFF(day,@Start,@End)+1 

pour les capturer faire :

DECLARE @Start datetime 
     ,@End datetime 
DECLARE @AllDates table 
     (Date datetime) 

SELECT @Start = '06/23/2008', @End = '06/30/2008' 

INSERT INTO @AllDates 
     (Date) 
    SELECT 
     @Start+Number-1 
     FROM Numbers 
     WHERE Number<=DATEDIFF(day,@Start,@End)+1 

SELECT * FROM @AllDates 

sortie:

Date 
----------------------- 
2008-06-23 00:00:00.000 
2008-06-24 00:00:00.000 
2008-06-25 00:00:00.000 
2008-06-26 00:00:00.000 
2008-06-27 00:00:00.000 
2008-06-28 00:00:00.000 
2008-06-29 00:00:00.000 
2008-06-30 00:00:00.000 

(8 row(s) affected)