SQL Server datetime LIKE auswählen?

92

in MySQL

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

Wie lautet die Syntax in SQL Server?

Paisal
quelle
Was möchten Sie eigentlich überprüfen? Dass eine bestimmte Datums- / Uhrzeitangabe einen bestimmten Datumsteil hat? Oder etwas anderes?
Chris J
1
Eine gesunde Diskussion darüber (einschließlich warum es schlecht ist, DATETIMEWerte wie Zeichenfolgen zu behandeln und warum es schlecht sein kann, sie zu verwenden BETWEENoder >= AND <=) finden Sie in diesem Blog von Aaron Bertrand .
Aaron Bertrand
Ihre Frage hat mindestens 5Stimmen für das Like-Operator- Tag. Könnte ich Sie bitten , SQL-like als Synonym vorzuschlagen ?
Kermit

Antworten:

138

Sie können die Funktion DATEPART () verwenden

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

Ich finde diesen Weg einfach zu lesen, da er die Zeitkomponente ignoriert und Sie das Datum des nächsten Tages nicht verwenden müssen, um Ihre Auswahl einzuschränken. Sie können zu mehr oder weniger Granularität wechseln, indem Sie zusätzliche Klauseln hinzufügen und den entsprechenden DatePart-Code verwenden, z

AND    DATEPART(hh, register_date) = 12)

um Aufzeichnungen zwischen 12 und 1 zu bekommen.

Die vollständige Liste der gültigen Argumente finden Sie in den MSDN DATEPART-Dokumenten .

Ralph Lavelle
quelle
Wenn es einen Index für register_date gibt, wird der Index vollständig ignoriert und die Leistung wird beeinträchtigt. Wahrscheinlich ziemlich schlecht.
Chris J
Ok, aber es vermeidet das Problem, das Zeichenfolgenäquivalent des Tages nach dem fraglichen Datum zu verwenden, das in einigen der Antworten hier vorgeschlagen wird. Schwierig, wenn das fragliche Datum das Ende des Monats oder Jahres ist.
Ralph Lavelle
59

Es gibt keine direkte Unterstützung für den LIKE-Operator für DATETIME-Variablen, aber Sie können DATETIME jederzeit in ein VARCHAR umwandeln:

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

Überprüfen Sie die MSDN-Dokumente auf eine vollständige Liste der verfügbaren "Stile" in der CONVERT-Funktion.

Marc

marc_s
quelle
1
stimmte zu - aber das OP forderte einen Weg, um mit / wie datetime umzugehen. Aber ich stimme zu - datetimes sollten vorzugsweise mit Bereichen wie> = und <= oder ZWISCHEN - viel besserer Ansatz
marc_s
Vielen Dank an alle. Entschuldigung, ich bin nur ein Neuling für SQL.
Paisal
1
Beachten Sie, dass MSSQL 2012 (ich denke auch ältere Versionen) datetime in varchar als '2014-01-06T16: 18: 00.045' konvertiert. Denken Sie also daran, wenn Sie versuchen, auch für Stunde / Minute zu passen.
Balint
Das einzige Problem, das ich mit der obigen SQL-Auswahl hatte, ist das folgende: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu
10

Wenn Sie dies tun, erzwingen Sie eine Zeichenfolgenkonvertierung. Es wäre besser, einen Start- / Enddatumbereich zu erstellen und Folgendes zu verwenden:

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

Dadurch kann der Index (falls vorhanden register_date) anstelle eines Tabellenscans verwendet werden.

Marc Gravell
quelle
Danke dir. Entschuldigung, ich bin nur ein Neuling für SQL.
Paisal
7

Sie können CONVERT verwenden, um das Datum in Textform abzurufen. Wenn Sie es in einen Varchar (10) konvertieren, können Sie = anstelle von like verwenden:

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

Sie können auch ein Datum für die obere und untere Grenze verwenden, mit dem zusätzlichen Vorteil, dass ein Index verwendet werden kann:

select *
from record
where '2009-10-10' <= register_date
and register_date < '2009-10-11'
Andomar
quelle
Ich denke, es gibt einen Tippfehler in der where-Klausel, es sollte "where '2009-10-10'> = register_date" sein
Vishwanath Dalvi
@mr_eclair: glaube nicht, das würde jedes Datum vor dem 11. Oktober
Andomar
7

Leider ist es nicht möglich, datetime mit 'LIKE' mit varchar zu vergleichen. Die gewünschte Ausgabe ist jedoch auf andere Weise möglich.

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

Sie können auch konvertieren verwenden, um das Datum mit LIKE durchsuchbar zu machen. Beispielsweise,

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

Der LIKEBediener arbeitet nicht mit Datumsteilen wie Monat oder Datum, der DATEPARTBediener jedoch.

Befehl, um alle Konten herauszufinden, deren Öffnungsdatum am 1. war:

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

* CASTING, OpenDtweil es Wert ist DATETIMEund nicht nur DATE.

Mohit Sarin
quelle
1

Es gibt eine sehr flockige Abdeckung des LIKE-Operators für Daten in SQL Server. Es funktioniert nur im amerikanischen Datumsformat. Als Beispiel könnten Sie versuchen:

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

Ich habe dies in SQL Server 2005 getestet und es funktioniert, aber Sie müssen wirklich verschiedene Kombinationen ausprobieren. Seltsame Dinge, die mir aufgefallen sind, sind:

  • Sie scheinen nur alles oder nichts für verschiedene Unterfelder innerhalb des Datums zu erhalten. Wenn Sie beispielsweise nach "Apr 2%" suchen, erhalten Sie nur etwas in den 20er Jahren - es werden die 2er weggelassen.

  • Die Verwendung eines einzelnen Unterstrichs '_' zur Darstellung eines einzelnen (Platzhalter-) Zeichens funktioniert nicht vollständig. Beispielsweise WHERE mydate LIKE 'oct _ 2010%'werden nicht alle Daten vor dem 10. zurückgegeben - es wird überhaupt nichts zurückgegeben!

  • Das Format ist starr amerikanisch: ' mmm dd yyyy hh:mm'

Ich habe es schwierig gefunden, einen Prozess für Sekunden festzunageln. Wenn also jemand etwas weiter gehen möchte, sei mein Gast!

Hoffe das hilft.

Paul
quelle
1

Ich bin etwas spät dran, aber tatsächlich gibt es eine direkte Unterstützung für den ähnlichen Operator in MS SQL Server.

Wie in der LIKE-Hilfe dokumentiert, wird versucht, den Datentyp in eine Zeichenfolge zu konvertieren, wenn es sich nicht um eine Zeichenfolge handelt. Und wie in der Dokumentation zu cast \ convert dokumentiert:

Die Standardkonvertierung von Datum und Uhrzeit in Zeichenfolge ist Typ 0 (, 100). Dies ist Mon TT TT JJJJ HH: MiAM (oder PM).

Wenn Sie ein solches Datum in der Datenbank haben:

2015-06-01 11:52:59.057

und Sie machen Fragen wie diese:

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'

Du bekommst diese Reihe.

Dieses Datumsformat deutet jedoch darauf hin, dass es sich um ein DateTime2 handelt. In der Dokumentation heißt es dann:

21 oder 121 - Kanonischer ODBC-Standard (mit Millisekunden) für Uhrzeit, Datum, Datum / Uhrzeit2 und Datum / Uhrzeit-Versatz. - JJJJ-mm-TT hh: mi: ss.mmm (24h)

Das macht es einfacher und Sie können verwenden:

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

und erhalten Sie den Rechnungsdatensatz. Hier ist ein Demo-Code:

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

Das Durchführen von Datetime-Suchen in SQL Server ohne Konvertierung in eine Zeichenfolge war schon immer problematisch. Das Abrufen jedes Datumsteils ist ein Overkill (der wahrscheinlich keinen Index verwenden würde). Wenn Sie keine Zeichenfolgenkonvertierung verwenden, ist es wahrscheinlich besser, Bereichsprüfungen zu verwenden. dh:

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

Versuche dies

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

Ich habe mein Problem so gelöst. Vielen Dank für Verbesserungsvorschläge. Beispiel 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 + "%'";
Eronildo Barbosa
quelle