Question

Je souhaite limiter un rapport à renvoyer des enregistrements de Date A à Date B. Voici ce que je faisais:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date between @startDate and @endDate

... ce qui m'a été rapporté a renvoyé les enregistrements de midi le 1er janvier à 23h59 le 31 mars (minuit est la valeur par défaut lorsque aucune heure n'est indiquée). Mais j’ai remarqué une différence, c’est-à-dire que si un disque a un temps de 00:00:00, il fera partie de cet ensemble.

Existe-t-il un moyen plus précis de procéder afin que la plage de dates souhaitée soit exactement renvoyée? *

J'ai essayé d'utiliser le temps:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008 00:00:00'
set @endDate = '04/01/2008 11:59:59'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date between @startDate and @endDate

... mais j'ai remarqué quelque chose de bizarre: SQL Server arrondit la centième de seconde. Je reçois donc ce disque du 1er avril (ha! Le disque du poisson d’avril! Grr) si j’utilise plus tard que 11:59:29. Pourquoi est-ce?

  • (Je suis sûr qu'il y en a un. Je suis nouveau dans ce domaine. Merci pour votre aide!)
Était-ce utile?

La solution

Il y a toujours l'option facile:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'

-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date >= @startDate 
and   date < @endDate

Autres conseils

Je soupçonne que la colonne de date dans view_Inspections est un type de données SmallDateTime. Ce type de données a une précision de 1 minute, ce qui explique vos résultats inattendus (en arrondissant les secondes à la minute près).

La méthode proposée par Roland Shaw est la meilleure façon de modifier votre requête pour répondre à vos besoins.

L'opérateur BETWEEN est inclusif, c'est pourquoi vous voyez les résultats obtenus dans votre première requête. L'arrondi que vous voyez dans votre deuxième requête dépendra du type de données date / heure exact que vous utilisez dans votre table. (BTW, je pense que vous confondez les secondes avec des centièmes de secondes). Il semble que vous utilisiez probablement une petite heure dans votre tableau, auquel cas l'heure est arrondie à la minute près.

Si votre table utilise datetime, essayez de convertir explicitement vos valeurs @startDate et @endDate en valeurs DATETIME (CAST (@endDate AS DATETIME)).

Une note rapide ... même pour les valeurs DATETIME, SQL Server n’est précis qu’au 3 / 100e de seconde; 11: 59: 59,999 sera donc arrondi à 12: 00: 00.000.

Vous avez essentiellement trois choix:

1) ENTRE CAST (01/01/2008 - 00: 00: 00.000 'AS DATETIME) ET CAST (03/31/2008 12: 59: 59.997' AS DATETIME)

2) ANNÉE (mon_date) = 2008 ET LE MOIS (mon_date) ENTRE 1 ET 3

3) ma_date > = CAST (01.01.2008 00: 00: 00.000 'AS DATETIME) ET ma_date < CAST (04/01/2008 - 00: 00: 00.000 'AS DATETIME)

La première méthode n’est pas très intuitive et, à mon avis, elle est sujette aux erreurs. La deuxième méthode tue les performances, car les index ne peuvent pas être utilisés et devient beaucoup plus complexe si vous pouvez effectuer des recherches sur plusieurs années ou bien commencer / terminer au milieu de mois. La troisième méthode, suggérée par Rowland, est la meilleure, selon moi.

Essayez simplement de supprimer l'heure du champ de date comme suit:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'

SELECT min(date),max(date) FROM view_Inspections 
WHERE CAST(FLOOR(CAST(date AS FLOAT)) AS DATETIME) BETWEEN CAST(@startDate AS DATETIME) And CAST(@startDate AS DATETIME))

Ceci renverra tout de 01/01/2008 00:00:00 à 04/01/2008 11:59:59.999. Si vous ne souhaitez pas que 04/01 soit inclus, définissez votre date de fin sur 03/31/2008.

Votre meilleure solution consiste simplement à créer un champ BIGINT (10) appelé & "julian &"; et de le stocker dans AAAAMMJJ.

Puis faites la requête où julian > = '20120103' ET julian < = '20120203'

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top