SQL Server tarih saat GİBİ seçin?


93

MySQL'de

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

SQL Server'daki sözdizimi nedir?


Gerçekte neyi kontrol etmek istiyorsunuz? Belirli bir tarih saatinin belirli bir tarih bölümü var mı? Veya başka bir şey?
Chris J

1
Bununla ilgili sağlıklı bir tartışma için ( DATETIMEdeğerlere dizeler gibi davranmanın neden kötü olduğu ve BETWEENveya kullanımının neden kötü olabileceği dahil >= AND <=), Aaron Bertrand'ın bu bloguna bakın .
Aaron Bertrand

Sorunuzda benzer operatör etiketi 5için en az oy var . Eşanlamlı olarak sql-like önermenizi rica edebilir miyim ?
Kermit

Yanıtlar:


139

DATEPART () işlevini kullanabilirsiniz

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

Zaman bileşenini görmezden geldiğinden ve seçiminizi kısıtlamak için sonraki günün tarihini kullanmak zorunda olmadığından bu yolu okumayı kolay buluyorum. Uygun DatePart kodunu kullanarak fazladan cümle ekleyerek daha büyük veya daha az ayrıntı düzeyine gidebilirsiniz, örn.

AND    DATEPART(hh, register_date) = 12)

12 ile 1 arasında yapılan kayıtları almak için.

Consult MSDN DATEPART docs geçerli argümanlar tam listesi için.


Register_date üzerinde bir indeks varsa, bu tamamen indeksi yok sayacak ve performans düşecektir. Muhtemelen oldukça kötüdür.
Chris J

Tamam, ancak buradaki birkaç cevapta önerildiği gibi, söz konusu tarihten sonraki günün dize eşdeğerini kullanma sorununu ortadan kaldırıyor. Söz konusu tarihin ayın veya yılın sonu olduğu zor.
Ralph Lavelle

61

DATETIME değişkenlerine karşı LIKE operatörü için doğrudan destek yoktur, ancak DATETIME değerini her zaman bir VARCHAR'a çevirebilirsiniz:

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

Kontrol MSDN dokümanlar CONVERT işlevinin mevcut "stilleri" tam listesi için.

Marc


1
kabul edildi - ancak OP, tarih saatini LIKE ile işlemek için bir yol istedi .... Ama kabul ediyorum - tarih zamanları tercihen> = ve <= veya ARASI - çok daha iyi yaklaşım
marc_s

Herkese teşekkürler. Üzgünüm, ben sadece SQL için acemiyim.
Paisal

1
Unutmayın, MSSQL 2012 (sanırım eski sürümler de) datetime'ı '2014-01-06T16: 18: 00.045' olarak dönüştürür, bu nedenle saat / dakika için de eşleştirmeye çalışırsanız bunu aklınızda bulundurun.
2014

Yukarıdaki sql seçiminde sahip olduğum tek sorun şudur: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu

10

Bunu yaparsanız, onu bir dize dönüşümü yapmaya zorluyorsunuz. Bir başlangıç ​​/ bitiş tarihi aralığı oluşturmak ve kullanmak daha iyi olur:

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

Bu, register_datebir tablo taraması yerine dizini (eğer varsa) kullanmasına izin verecektir .


Teşekkür ederim. Üzgünüm, ben sadece SQL için acemiyim.
Paisal

8

Tarihi metin biçiminde almak için CONVERT'i kullanabilirsiniz. Bunu bir varchar (10) 'a dönüştürürseniz, bunun yerine = kullanabilirsiniz:

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

Ya da bir üst ve alt sınır tarihi kullanabilirsiniz, bunun bir endeksi kullanma avantajı vardır:

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

Sanırım where cümlesinde yazım hatası var, "where '2009-10-10'> = register_date" olmalıdır
Vishwanath Dalvi

@mr_eclair: Öyle düşünmeyin, bu 11 Ekim'den önceki her tarihi içerir
Andomar

7

Ne yazık ki, tarih-saati varchar ile 'LIKE' kullanarak karşılaştırmak mümkün değildir. Ancak istenen çıktı başka bir şekilde mümkündür.

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

3

Ayrıca, tarihi LIKE kullanarak aranabilir hale getirmek için dönüştür seçeneğini de kullanabilirsiniz. Örneğin,

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

2

LIKEOperatör ay veya tarih gibi tarih parçalarla çalışmıyor ama DATEPARToperatör yok.

Açılış Tarihi 1. gün olan tüm hesapları bulma komutu:

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

* DÖKÜM OpenDtçünkü onun değeri içindedir DATETIMEve sadece değil DATE.


2

Bunu dene

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

1

SQL Server'daki tarihler için LIKE işlecinin çok kesintili bir kapsamı vardır. Yalnızca Amerikan tarih biçimini kullanarak çalışır. Örnek olarak şunları deneyebilirsiniz:

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

Bunu SQL Server 2005'te test ettim ve işe yarıyor, ancak gerçekten farklı kombinasyonları denemeniz gerekecek. Fark ettiğim tuhaf şeyler:

  • Yalnızca tarih içinde farklı alt alanlar için tümü veya hiçbir şey almamış gibi görünüyorsunuz, örneğin, "% 2 nisan" ararsanız, yalnızca 20'li yıllarda herhangi bir şey elde edersiniz - 2.'leri atlar.

  • Tamamen iş, örneğin olmayan bir tek (joker) karakteri temsil etmek '_' Tek bir çizgi kullanarak WHERE mydate LIKE 'oct _ 2010%'olacak değil tüm tarihleri iade önce aslında, hiç bir şey döndürür - 10!

  • Biçim katı Amerikan'dır: ' mmm dd yyyy hh:mm'

Bir süreci GİBİ saniyeler içinde tamamlamakta zorlandım, bu yüzden bunu biraz daha ileri götürmek isteyen varsa, konuğum olun!

Bu yardımcı olur umarım.


1

Bu iş parçacığına biraz geç kaldım, ancak aslında MS SQL sunucusunda benzer operatör için doğrudan destek var.

LIKE yardımında belgelendiği gibi, veri türü bir dizge değilse, onu bir dizeye dönüştürmeye çalışılır. Ve cast \ convert belgelerinde belirtildiği gibi:

dizeye varsayılan tarih saat dönüşümü, mon gg yyyy hh: miAM (veya PM) olan 0 (, 100) türüdür.

DB'de böyle bir randevunuz varsa:

2015-06-01 11:52:59.057

ve bunun gibi sorgular yaparsınız:

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'

o sırayı al.

Bununla birlikte, bu tarih biçimi bunun bir DateTime2 olduğunu gösterir , ardından belgeler şunları söyler:

21 veya 121 - ODBC kanonik (milisaniye ile) saat, tarih, tarih saat2 ve tarih saat ofset için varsayılan. - yyyy-aa-gg ss: mi: ss.mmm (24s)

Bu işi kolaylaştırır ve şunları kullanabilirsiniz:

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

ve fatura kaydını alın. İşte bir demo kodu:

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

SQL sunucusunda dizeye herhangi bir dönüştürme yapmadan datetime aramaları yapmak her zaman sorunlu olmuştur. Her tarih bölümünü almak aşırı bir şeydir (muhtemelen bir indeks kullanır). Dize dönüştürme kullanmadığınızda muhtemelen daha iyi bir yol, aralık kontrollerini kullanmaktır. yani:

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

0

Sorunumu bu şekilde çözdüm. İyileştirme önerileriniz için teşekkür ederiz. C # 'da örnek.

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 + "%'";
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.