Requête SQL pour sélectionner des dates entre deux dates

303

J'ai un start_dateet end_date. Je veux obtenir la liste des dates entre ces deux dates. Quelqu'un peut-il m'aider à signaler l'erreur dans ma requête?

select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and Date between 2011/02/25 and 2011/02/27

Voici Dateune datetimevariable.

Neeraj
la source

Réponses:

484

vous devez mettre ces deux dates entre guillemets simples comme ..

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date between '2011/02/25' and '2011/02/27'

ou peut utiliser

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date >= '2011/02/25' and Date <= '2011/02/27'

gardez à l'esprit que la première date est inclusive, mais la seconde est exclusive, car elle est effectivement '2011/02/27 00:00:00'

Deepak
la source
42
SQL Server définit par défaut une date sans heure à 00:00:00. Cette requête ne retournera-t-elle donc rien des 25/02/2011 et 26/02/2011 à minuit?
Matt
5
@Deepak, votre deuxième bit devrait dire> = et <=
IndoKnight
3
Vous pourriez mentionner que l'ordre est important dans la fonction ENTRE. Elle doit aller du plus ancien à gauche et du plus récent à droite. Cela n'est pas intuitif car = est un opérateur comparatif dans sql et fonctionne à la fois pour "EmployeeId = 1" ou "1 = EmployeeId" dans la clause where.
Fi Horan
@Matt, selon la documentation pour entre , si une ligne avait une date du 27/02/2011 sans heure, alors cette ligne équivaut à avoir une date du 27/02/2011 00:00 et serait retournée dans le requête, car elle est inférieure ou égale à 2011/02/27 00:00. Donc, si vous ne traitez pas avec le temps, betweendevrait fonctionner comme prévu.
timctran
@timctran C'est vrai, mais 2011/02/27 00:00 est ce que nous appellerions à minuit le 26/02/2011. Vraisemblablement, la requête signifie d'inclure le 27 dans l'ensemble de résultats - mais une entrée avec un horodatage de 2011/02/27 5:00 ne serait pas incluse.
Sinjai
128

Étant donné qu'un datetime sans segment de temps spécifié aura une valeur de date 00:00:00.000, si vous voulez être sûr d'obtenir toutes les dates de votre plage, vous devez soit fournir l'heure de votre date de fin, soit augmenter votre date de fin et l'utiliser <.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/27 23:59:59.999'

OU

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date < '2011/02/28'

OU

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date <= '2011/02/27 23:59:59.999'

N'UTILISEZ PAS les éléments suivants, car cela pourrait renvoyer certains enregistrements du 28/02/2011 si leur heure est 00: 00: 00.000.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/28'
WelshDragon
la source
42
Les gens regardent toujours ces questions et réponses, même si elles ont été posées à l'origine il y a quelque temps. Je suis venu chercher une réponse, et une grande partie de ce que j'ai vu ici était incomplète ou absolument incorrecte. Ma réponse n'aidera pas l'affiche originale, mais cela pourrait aider quelqu'un, peut-être même dans trois ans.
WelshDragon
3
Votre réponse m'a beaucoup aidé, @WelshDragon - Les autres réponses ont laissé de côté le fait que le format de la date doit être "simple date" sur le serveur pour ignorer les heures. "<= END_DATE" suppose 12h, ce que je ne savais pas. J'effectuais une requête avec "... <= 01/01/2014" et je n'ai pas pu comprendre pourquoi les commandes à cette date n'étaient pas affichées pour le 1er. Merci beaucoup.
Keith
@WelshDragon - votre réponse est un très bon matériel pour utiliser les dates comme clause where. Merci
Jack Frost
qu'est-ce qui ne va pas s'il revient '2011/02/28 00:00:00.000'?
Muflix
1
J'ai essayé aujourd'hui, vous pouvez également utiliser convert(date, Date) between '2011/02/25' and '2011/02/27'(au moins avec un MS SQL Server récent). La convert()partie se chargera de supprimer la partie temps et la comparaison entre fonctionnera alors comme prévu.
sensei
14

Essaye ça:

select Date,TotalAllowance from Calculation where EmployeeId=1
             and [Date] between '2011/02/25' and '2011/02/27'

Les valeurs de date doivent être saisies sous forme de chaînes.

Pour garantir la pérennité de votre requête pour SQL Server 2008 et versions ultérieures, Date versions il convient de l'échapper car il s'agit d'un mot réservé dans les versions ultérieures.

Gardez à l'esprit que les dates sans heures prennent minuit comme valeurs par défaut, il se peut donc que vous n'ayez pas la bonne valeur.


la source
1
La date n'est pas un mot-clé et n'a pas besoin d'être échappée. La mise en évidence de la syntaxe n'est qu'une mise en évidence de la syntaxe, les mots clés ne doivent être échappés que s'ils provoquent une erreur de syntaxe. Il est également recommandé d'utiliser la conversion explicite au lieu de la conversion implicite des constantes de chaîne de données. - et Date entre CAST ('2011/02 / 25'AS DATETIME) et CAST (' 2011/02 / 27'AS DATETIME)
tponthieux
5
Naturellement, vous avez raison s'il s'agit de SQL Server 2005, que l'OP a étiqueté. Cependant, la date est réservée en 2008 et plus, donc pour la pérennité, il n'y a aucun mal à y échapper. J'ai édité ma réponse.
1
S'il spécifiait la date unique pour les deux, il retournerait zéro lignes mais je suppose que ce n'est pas l'exigence de l'op
Zo a le
12
select * from table_name where col_Date between '2011/02/25' 
AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

Ici, ajoutez d'abord un jour à la date de fin actuelle, ce sera 2011-02-28 00:00:00, puis vous soustrayez une seconde pour faire la date de fin 2011-02-27 23:59:59. En faisant cela, vous pouvez obtenir toutes les dates entre les intervalles donnés.

output:
2011/02/25
2011/02/26
2011/02/27
Chandra Prakash
la source
8
select * from test 
     where CAST(AddTime as datetime) between '2013/4/4' and '2014/4/4'

- si le type de données est différent

hamze shoae
la source
5

Cette requête est idéale pour récupérer les valeurs entre la date actuelle et ses 3 prochaines dates

SELECT * FROM tableName  WHERE columName 
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)

Cela ajoutera éventuellement 3 jours supplémentaires de tampon à la date actuelle.

Vinit Kadkol
la source
5

C'est très ancien, mais étant donné les nombreuses expériences que j'ai eues avec les dates, vous voudrez peut-être considérer ceci: les gens utilisent des paramètres régionaux différents, en tant que tels, certaines personnes (et certaines bases de données / ordinateurs, selon les paramètres régionaux) peuvent lire ceci le 11/12/2016 comme le 11 décembre 2016 ou le 12 novembre 2016. Encore plus, le 16/11/12 fourni à la base de données MySQL sera converti en interne au 12 novembre 2016, tandis que la base de données Access fonctionnant sur un ordinateur de configuration régionale britannique interprétera et stockez-le le 16 novembre 2012.

Par conséquent, je me suis fixé comme politique d'être explicite chaque fois que je vais interagir avec des dates et des bases de données. Je fournis donc toujours mes requêtes et codes de programmation comme suit:

SELECT FirstName FROM Students WHERE DoB >= '11 Dec 2016';

Notez également qu'Access acceptera le #, donc:

SELECT FirstName FROM Students WHERE DoB >= #11 Dec 2016#;

mais le serveur MS SQL ne le fera pas, donc j'utilise toujours "'" comme ci-dessus, ce que les deux bases de données acceptent.

Et lorsque j'obtiens cette date à partir d'une variable dans le code, je convertis toujours le résultat en chaîne comme suit:

"SELECT FirstName FROM Students WHERE DoB >= " & myDate.ToString("d MMM yyyy")

J'écris ceci parce que je sais que parfois certains programmeurs peuvent ne pas être assez désireux de détecter la conversion inhérente. Il n'y aura pas d'erreur pour les dates <13, juste des résultats différents!

Quant à la question posée, ajoutez un jour à la dernière date et faites la comparaison comme suit:

dated >= '11 Nov 2016' AND dated < '15 Nov 2016' 
Hannington Mambo
la source
vos informations ont aidé à compléter ma tâche. j'ai travaillé dessus pendant plus de 10 heures et aucune des réponses ne fonctionnerait pour moi. Quand je concatène comme vous l'avez montré, mon projet fonctionne très bien. mais la règle semble être de ne pas écrire une instruction SQL comme celle-ci. chaque fois que j'essaie de définir le SqlCommand pour ajouter les paramètres de date à l'instruction SQL, les paramètres ne seront pas attachés et j'obtiens l'erreur que je dois déclarer "@startDate" et "@endDate". je ne peux pas passer ce problème. J'ai essayé votre format de date "jj MMM aaaa" qui a fonctionné et j'ai également essayé "aaaa MMM jj" qui a également effectué la même chose.
Dave Hampel
Super ça a aidé! Ci-dessus, des exemples de code. Il est toujours préférable de déclarer et d'utiliser des paramètres pour éviter l'injection SQL. Et il semble que vous soyez déjà requis / protégé par les règles de votre projet, ce qui est bien.
Hannington Mambo
4
select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and convert(varchar(10),Date,111) between '2011/02/25' and '2011/02/27'
njtd
la source
3

Essayez de mettre les dates entre # # par exemple:

#2013/4/4# and #2013/4/20#

Ça a marché pour moi.

Aleksandar
la source
1
Que fait # dans ce contexte?
BK
@BK c'est un délimiteur, comme les guillemets pour les chaînes. "Lorsque vous fournissez des valeurs à une instruction SQL, par exemple en tant que critères de requête, leur type de données doit être correctement défini par un" qualificatif ". Cela se fait en enfermant la valeur entre une paire de caractères appropriés." référence -> lien
Aleksandar
1
@BK S'il s'agit d'une syntaxe TSql, vous devrez utiliser des guillemets simples ( ' ) pour obtenir ce dont vous avez besoin. références * notions de base de sql-fontstuff.com * Début SQL - Paul Wilton, John Colby
Aleksandar
1
Il ne peut être plus clair que la question concerne SQL Server et T-SQL. T-SQL et SQL Server n'acceptent pas les dates entre les balises de hachage, il accepte les dates entre guillemets simples. Cette réponse est fausse.
TT.
@TT. le nombre de votes positifs indique que cela a quand même aidé quelqu'un. Au moment où j'ai écrit ma réponse, la réponse acceptée était déjà choisie. Pourtant, j'ai écrit ceci pour aider tous ceux qui pourraient venir ici de Google ou d'ailleurs :)
Aleksandar
2

si sa date dans 24 heures et commence le matin et se termine la nuit devrait ajouter quelque chose comme:

declare @Approval_date datetime
set @Approval_date =getdate()
Approval_date between @Approval_date +' 00:00:00.000' and @Approval_date +' 23:59:59.999'
Sheryar Nizar
la source
1

meilleure requête pour la date sélectionnée entre la date actuelle et les trois derniers jours :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN       
DATE_SUB(CURDATE(), INTERVAL 3 DAY)  AND CURDATE() 

meilleure requête pour la date sélectionnée entre la date actuelle et les trois prochains jours :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN   
   CURDATE()  AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)   
user3223432
la source
1

Consultez les exemples ci-dessous: à la fois fonctionnels et non fonctionnels.

select * from tblUser Where    
convert(varchar(10),CreatedDate,111) between '2015/04/01' and '2016/04/01' //--**Working**

OU

select * from tblUser Where
(CAST(CreatedDate AS DATETIME) between CAST('2015/04/01' AS DATETIME) And CAST('2016/4/30'AS DATETIME)) //--**Working**

OU

select * from tblUser Where
(YEAR(CreatedDate) between YEAR('2015/04/01') And YEAR('2016/4/30')) 
//--**Working**

ET ci-dessous ne fonctionne pas:

select * from tblUser Where
Convert(Varchar(10),CreatedDate,111) >=  Convert(Varchar(10),'01-01-2015',111) and  Convert(Varchar(10),CreatedDate,111) <= Convert(Varchar(10),'31-12-2015',111) //--**Not Working**


select * from tblUser Where
(Convert(Varchar(10),CreatedDate,111) between Convert(Varchar(10),'01-01-2015',111) And Convert(Varchar(10),'31-12-2015',111)) //--**Not Working**
Tobbin Well
la source
1

nous pouvons utiliser entre pour afficher deux données de dates, mais cela cherchera toutes les données et les comparera, ce qui ralentira notre processus pour les données énormes, donc je suggère à tout le monde d'utiliser datediff:

qry = "SELECT * FROM [calender] WHERE datediff(day,'" & dt & "',[date])>=0 and datediff(day,'" & dt2 & "',[date])<=0 "

ici le calendrier est le tableau, dt comme variable de date de début et dt2 est la variable de date de fin.

Bipul Roy
la source
0

J'aime utiliser la syntaxe '1 MonthName 2015' pour les dates ex:

   WHERE aa.AuditDate>='1 September 2015'
     AND aa.AuditDate<='30 September 2015'

pour les dates

Juan
la source
0

J'irais pour

select Date,TotalAllowance from Calculation where EmployeeId=1
             and Date >= '2011/02/25' and Date < DATEADD(d, 1, '2011/02/27')

La logique étant d' >=inclure la date de début entière et d' <exclure la date de fin, nous ajoutons donc une unité à la date de fin. Cela peut s'adapter pendant des mois, par exemple:

select Date, ... from ...
             where Date >= $start_month_day_1 and Date < DATEADD(m, 1, $end_month_day_1)
entonio
la source
0
Select 
    * 
from 
    Calculation 
where 
    EmployeeId=1 and Date between #2011/02/25# and #2011/02/27#;
Saad Sheikh
la source
0

Vous pouvez essayer ce SQL

select * from employee where rec_date between '2017-09-01' and '2017-09-11' 
Kamran
la source
0

Vraiment, toutes les dates sql doivent être au format aaaa-MM-jj pour des résultats plus précis.

Robert Peter Bronstein
la source
0
/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 10 [Id]
  ,[Id_parvandeh]
  ,[FirstName]
  ,[LastName]
  ,[RegDate]
  ,[Gilder]
  ,[Nationality]
  ,[Educ]
  ,[PhoneNumber]
  ,[DueInMashhad]

  ,[EzdevajDate]


  ,[MarriageStatus]
  ,[Gender]
  ,[Photo]

  ,[ModifiedOn]
  ,[CreatorIp]
   From
  [dbo].[Socials] where educ >= 3 or EzdevajDate  >= '1992/03/31' and EzdevajDate <= '2019/03/09' and MarriageStatus = 1
Mojtaba Nava
la source
-2

il vaut mieux écrire de cette façon:

CREATE PROCEDURE dbo.Get_Data_By_Dates
(
    @EmployeeId INT = 1,
    @Start_Date DATE,
    @End_Date Date
)
AS
Select * FROM Calculation  
    where EmployeeId=@EmployeeId AND Test_Date BETWEEN @Start_Date AND @End_Date
RETURN
Hadi
la source
1
L'utilisation d'une procédure stockée dans cette situation n'aura aucun sens car elle réduira horriblement la flexibilité de la requête SQL, elle sera si spécifique, si vous ne voulez pas l'utiliser dans une situation vraiment spécifique, veuillez ne pas utiliser de Procédure stockée - Il existe également de nombreuses améliorations disponibles pour votre procédure stockée que vous pouvez les trouver dans cette communauté;).
shA.t
-6
SELECT Date, TotalAllowance  
FROM Calculation  
WHERE EmployeeId = 1 
  AND Date BETWEEN to_date('2011/02/25','yyyy-mm-dd') 
               AND to_date ('2011/02/27','yyyy-mm-dd');
Ankita
la source
1
Vous pensiez probablement à Oracle SQL lorsque vous avez écrit cette réponse. Ceci est valable dans Oracle. Pas tellement dans SQL Server (d'après ce que je peux voir).
Charles Caldwell