SQL Server datetime LIKE selezionare?


92

in MySQL

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

Qual è la sintassi in SQL Server?


Cosa vuoi controllare effettivamente? Che un dato datetime ha una data parte? O qualcos'altro?
Chris J,

1
Per una discussione sana su questo (incluso il motivo per cui è sbagliato trattare i DATETIMEvalori come stringhe e perché può essere sbagliato da usare BETWEENo >= AND <=), vedere questo blog di Aaron Bertrand .
Aaron Bertrand,

La tua domanda ha almeno 5voti per il tag like-operator . Potrei gentilmente chiederti di suggerire sql-like come sinonimo ?
Kermit

Risposte:


138

È possibile utilizzare la funzione DATEPART ()

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

Trovo questo modo facile da leggere, poiché ignora la componente temporale e non è necessario utilizzare la data del giorno successivo per limitare la selezione. Puoi passare a una maggiore o minore granularità aggiungendo clausole extra, utilizzando il codice DatePart appropriato, ad es

AND    DATEPART(hh, register_date) = 12)

per ottenere record realizzati tra 12 e 1.

Consulta i documenti MSDN DATEPART per l'elenco completo degli argomenti validi.


Se c'è un indice su register_date, questo ignorerà completamente l'indice e le prestazioni ne risentiranno. Probabilmente piuttosto male.
Chris J,

Ok, ma evita il problema di utilizzare l'equivalente stringa del giorno dopo la data in questione, che viene suggerito in alcune delle risposte qui. Difficile dove la data in questione è la fine del mese o dell'anno.
Ralph Lavelle,

59

Non esiste un supporto diretto per l'operatore LIKE contro le variabili DATETIME, ma puoi sempre eseguire il cast di DATETIME su un VARCHAR:

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

Controllare i documenti MSDN per un elenco completo degli "stili" disponibili nella funzione CONVERT.

Marc


1
d'accordo - ma l'OP ha richiesto un modo per gestire il datetime con LIKE .... Ma sono d'accordo - i datetimes dovrebbero essere preferibilmente gestiti con intervalli come> = e <= o BETWEEN - approccio molto migliore
marc_s

Grazie a tutti. Scusa, sono solo un principiante di SQL.
Paisal

1
Tieni presente che MSSQL 2012 (immagino anche le versioni precedenti) convertirà datetime in varchar come "2014-01-06T16: 18: 00.045", quindi tienilo a mente se provi ad abbinare anche per ora / minuto.
balint

L'unico problema che ho avuto con la selezione sql sopra è questo: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu

10

Se lo fai, lo costringi a fare una conversione di stringa. Sarebbe meglio creare un intervallo di date di inizio / fine e utilizzare:

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

Ciò consentirà di utilizzare l'indice (se presente register_date), piuttosto che una scansione della tabella.


Grazie. Scusa, sono solo un principiante di SQL.
Paisal

7

È possibile utilizzare CONVERT per ottenere la data in formato testo. Se lo converti in un varchar (10), puoi usare = invece di come:

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

Oppure puoi utilizzare una data limite superiore e inferiore, con l'ulteriore vantaggio di poter utilizzare un indice:

select *
from record
where '2009-10-10' <= register_date
and register_date < '2009-10-11'

Penso che ci sia un errore di battitura nella clausola where, dovrebbe essere "where '2009-10-10'> = register_date"
Vishwanath Dalvi

@mr_eclair: non credo, includerebbe ogni data prima dell'11 ottobre
Andomar

7

Sfortunatamente, non è possibile confrontare datetime con varchar usando 'LIKE' ma l'output desiderato è possibile in un altro modo.

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

3

Puoi anche usare convert per rendere la data ricercabile usando MI PIACE. Per esempio,

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

2

L' LIKEoperatore non lavora con parti della data come il mese o la data, ma l' DATEPARToperatore lo fa.

Comando per scoprire tutti gli account la cui data di apertura è stata il 1 °:

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

* CASTING OpenDtperché il suo valore è dentro DATETIMEe non solo DATE.


1

C'è una copertura molto instabile dell'operatore LIKE per le date in SQL Server. Funziona solo utilizzando il formato data americano. Ad esempio potresti provare:

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

L'ho testato in SQL Server 2005 e funziona, ma dovrai davvero provare diverse combinazioni. Le cose strane che ho notato sono:

  • Sembra che tu ottenga tutto o niente per diversi sottocampi entro la data, ad esempio, se cerchi "apr 2%" ottieni solo qualcosa nel 20 ° - omette il 2 °.

  • Utilizzando un unico sottolineatura '_' per rappresentare un singolo carattere (jolly) non tutto il lavoro, per esempio, WHERE mydate LIKE 'oct _ 2010%'sarà non tornare tutte le date prima del 10 - restituisce nulla, in effetti!

  • Il formato è rigido americano: ' mmm dd yyyy hh:mm'

Ho trovato difficile definire un processo per LIKEing secondi, quindi se qualcuno vuole andare un po 'oltre, sii mio ospite!

Spero che questo ti aiuti.


1

Sono un po 'in ritardo su questo thread, ma in realtà c'è il supporto diretto per l'operatore simile nel server MS SQL.

Come documentato nella guida LIKE, se il tipo di dati non è una stringa, si tenta di convertirlo in una stringa. E come documentato nella documentazione cast \ convert:

La conversione predefinita di datetime in stringa è di tipo 0 (, 100) che è lun gg aaaa hh: miAM (o PM).

Se hai una data come questa nel DB:

2015-06-01 11:52:59.057

e fai domande come questa:

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'

hai quella riga.

Tuttavia, questo formato di data suggerisce che si tratta di un DateTime2 , quindi la documentazione dice:

21 o 121: impostazione predefinita canonica ODBC (con millisecondi) per ora, data, datetime2 e datetimeoffset. - aaaa-mm-gg hh: mi: ss.mmm (24h)

Questo lo rende più facile e puoi usare:

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

e ottieni il record della fattura. Ecco un codice demo:

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%';

L'esecuzione di ricerche datetime nel server SQL senza alcuna conversione in stringa è sempre stata problematica. Ottenere ogni parte della data è eccessivo (che improbabilmente userebbe un indice). Probabilmente un modo migliore quando non usi la conversione di stringhe sarebbe usare i controlli di intervallo. cioè:

select * from record 
where register_date >= '20091010' and register_date < '20091011';

1

Prova questo

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

0

Ho risolto il mio problema in questo modo. Grazie per suggerimenti per miglioramenti. Esempio in 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 + "%'";
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.