SQL Server datetime LIKE sélectionnez?

92

dans MySQL

select * from record where register_date like '2009-10-10%'

Quelle est la syntaxe de SQL Server?

Paisal
la source
Que voulez-vous vraiment vérifier? Qu'une date-heure donnée a une partie de date donnée? Ou autre chose?
Chris J
1
Pour une discussion saine à ce sujet (y compris pourquoi il est mauvais de traiter les DATETIMEvaleurs comme des chaînes, et pourquoi il peut être mauvais à utiliser BETWEENou >= AND <=), consultez ce blog d'Aaron Bertrand .
Aaron Bertrand
Votre question a au moins des 5votes pour la balise comme opérateur . Pourrais - je demander de bien vouloir vous suggérer sql comme un synonyme ?
Kermit

Réponses:

138

Vous pouvez utiliser la fonction DATEPART ()

SELECT * FROM record 
WHERE  (DATEPART(yy, register_date) = 2009
AND    DATEPART(mm, register_date) = 10
AND    DATEPART(dd, register_date) = 10)

Je trouve cela facile à lire, car il ignore la composante heure et vous n'avez pas à utiliser la date du lendemain pour restreindre votre sélection. Vous pouvez aller à une granularité plus ou moins grande en ajoutant des clauses supplémentaires, en utilisant le code DatePart approprié, par exemple

AND    DATEPART(hh, register_date) = 12)

pour obtenir des enregistrements entre 12 et 1.

Consultez la documentation MSDN DATEPART pour obtenir la liste complète des arguments valides.

Ralph Lavelle
la source
S'il y a un index sur register_date, cela ignorera complètement l'index et les performances en souffriront. Probablement assez mal.
Chris J
Ok, mais cela évite le problème de l'utilisation de la chaîne équivalente du jour après la date en question, ce qui est suggéré dans quelques-unes des réponses ici. Tricky où la date en question est la fin du mois ou de l'année.
Ralph Lavelle
60

Il n'y a pas de prise en charge directe de l'opérateur LIKE sur les variables DATETIME, mais vous pouvez toujours convertir le DATETIME en VARCHAR:

SELECT (list of fields) FROM YourTable
WHERE CONVERT(VARCHAR(25), register_date, 126) LIKE '2009-10-10%'

Consultez la documentation MSDN pour obtenir une liste complète des «styles» disponibles dans la fonction CONVERT.

Marc

marc_s
la source
1
d'accord - mais l'OP a demandé un moyen de gérer datetime avec LIKE .... Mais je suis d'accord - les datetimes devraient de préférence être gérées avec des plages comme> = et <= ou BETWEEN - bien meilleure approche
marc_s
Merci tout le monde. Désolé, je ne suis qu'un débutant pour SQL.
Paisal
1
Sachez que le MSSQL 2012 (je suppose que les anciennes versions aussi) convertira datetime en varchar en tant que `` 2014-01-06T16: 18: 00.045 '', alors gardez cela à l'esprit si vous essayez également de faire correspondre heure / minute.
balint
Le seul problème que j'ai eu avec la sélection SQL ci-dessus est le suivant: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu
10

Si vous faites cela, vous le forcez à effectuer une conversion de chaîne. Il serait préférable de créer une plage de dates de début / fin et d'utiliser:

declare @start datetime, @end datetime
select @start = '2009-10-10', @end = '2009-11-10'
select * from record where register_date >= @start
           and register_date < @end

Cela lui permettra d'utiliser l'index (s'il y en a un register_date), plutôt qu'une analyse de table.

Marc Gravell
la source
Je vous remercie. Désolé, je ne suis qu'un débutant pour SQL.
Paisal
8

Vous pouvez utiliser CONVERT pour obtenir la date sous forme de texte. Si vous le convertissez en varchar (10), vous pouvez utiliser = au lieu de like:

select *
from record
where CONVERT(VARCHAR(10),register_date,120) = '2009-10-10'

Ou vous pouvez utiliser une date limite supérieure et inférieure, avec l'avantage supplémentaire de pouvoir utiliser un index:

select *
from record
where '2009-10-10' <= register_date
and register_date < '2009-10-11'
Andomar
la source
Je pense qu'il y a une faute de frappe dans la clause where, ça devrait être "where '2009-10-10'> = register_date"
Vishwanath Dalvi
@mr_eclair: ne pense pas, cela inclurait toutes les dates avant le 11 octobre
Andomar
7

Malheureusement, il n'est pas possible de comparer datetime vers varchar en utilisant 'LIKE', mais la sortie souhaitée est possible d'une autre manière.

    select * from record where datediff(dd,[record].[register_date],'2009-10-10')=0
Dani Mathew
la source
3

Vous pouvez également utiliser convert pour rendre la date consultable à l'aide de LIKE. Par exemple,

select convert(VARCHAR(40),create_date,121) , * from sys.objects where     convert(VARCHAR(40),create_date,121) LIKE '%17:34%'
Steve M
la source
2

L' LIKEopérateur ne travaille pas avec des parties de date comme le mois ou la date, mais l' DATEPARTopérateur le fait.

Commande pour découvrir tous les comptes dont la date d'ouverture était le 1er:

SELECT * 
  FROM Account 
 WHERE DATEPART(DAY, CAST(OpenDt AS DATE)) = 1`

* CASTING OpenDtparce que sa valeur est DATETIMEet pas seulement DATE.

Mohit Sarin
la source
1

Il existe une couverture très irrégulière de l'opérateur LIKE pour les dates dans SQL Server. Cela fonctionne uniquement en utilisant le format de date américain. À titre d'exemple, vous pouvez essayer:

... WHERE register_date LIKE 'oct 10 2009%'

J'ai testé cela dans SQL Server 2005 et cela fonctionne, mais vous devrez vraiment essayer différentes combinaisons. Les choses étranges que j'ai remarquées sont:

  • Vous semblez n'obtenir tout ou rien pour les différents sous-champs dans la date, par exemple, si vous recherchez 'apr 2%', vous n'obtenez rien dans les 20e - il omet les seconds.

  • L' utilisation d' un seul trait de soulignement « _ » pour représenter un seul caractère (générique) ne fonctionne pas tout à fait, par exemple, WHERE mydate LIKE 'oct _ 2010%'ne pas retourner toutes les dates avant le 10 - il ne retourne rien du tout, en fait!

  • Le format est rigide américain: ' mmm dd yyyy hh:mm'

J'ai eu du mal à définir un processus pour LIKEing secondes, donc si quelqu'un veut aller un peu plus loin, soyez mon invité!

J'espère que cela t'aides.

Paul
la source
1

Je suis un peu en retard sur ce fil, mais en fait, il existe un support direct pour l'opérateur like dans le serveur MS SQL.

Comme indiqué dans l'aide LIKE, si le type de données n'est pas une chaîne, il est tenté de le convertir en chaîne. Et comme documenté dans la documentation cast \ convert:

La conversion de date / heure par défaut en chaîne est de type 0 (, 100) qui est mon jj aaaa hh: miAM (ou PM).

Si vous avez une date comme celle-ci dans la base de données:

2015-06-01 11:52:59.057

et vous faites des requêtes comme celle-ci:

select * from wws_invoice where invdate like 'Jun%'
select * from wws_invoice where invdate like 'Jun 1%'
select * from wws_invoice where invdate like 'Jun 1 %'
select * from wws_invoice where invdate like 'Jun 1 2015:%'
select * from wws_invoice where invdate like 'Jun ? 2015%'
...
select * from wws_invoice where invdate like 'Jun 1 2015 11:52AM'

vous obtenez cette ligne.

Cependant, ce format de date suggère qu'il s'agit d'un DateTime2 , alors la documentation dit:

21 ou 121 - ODBC canonique (avec millisecondes) par défaut pour l'heure, la date, datetime2 et datetimeoffset. - aaaa-mm-jj hh: mi: ss.mmm (24h)

Cela facilite les choses et vous pouvez utiliser:

select * from wws_invoice where invdate like '2015-06-01%'

et obtenez l'enregistrement de la facture. Voici un code de démonstration:

DECLARE @myDates TABLE (myDate DATETIME2);
INSERT INTO @myDates (myDate)
VALUES
('2015-06-01 11:52:59.057'),
('2015-06-01 11:52:59.054'),
('2015-06-01 13:52:59.057'),
('2015-06-01 14:52:59.057');

SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11:52:59%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11:52:59.054%';

Faire des recherches datetime dans le serveur SQL sans aucune conversion en chaîne a toujours été problématique. Obtenir chaque partie de date est une exagération (qui utiliserait peu probablement un index). Un meilleur moyen lorsque vous n'utilisez pas de conversion de chaîne serait probablement d'utiliser des vérifications de plage. c'est à dire:

select * from record 
where register_date >= '20091010' and register_date < '20091011';
Cetin Basoz
la source
1

Essaye ça

SELECT top 10 * from record WHERE  IsActive = 1 and CONVERT(VARCHAR, register_date, 120) LIKE '2020-01%'
Roche
la source
0

J'ai résolu mon problème de cette façon. Merci pour les suggestions d'améliorations. Exemple en C #.

string dd, mm, aa, trc, data;
dd = nData.Text.Substring(0, 2);
mm = nData.Text.Substring(3, 2);
aa = nData.Text.Substring(6, 4);
trc = "-";
data = aa + trc + mm + trc + dd;

"Select * From bdPedidos Where Data Like '%" + data + "%'";
Eronildo Barbosa
la source