SQL Server datetime LIKE เลือก?


92

ใน MySQL

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

ไวยากรณ์ใน SQL Server คืออะไร?


คุณต้องการตรวจสอบอะไรจริงๆ วันที่และเวลาที่ระบุมีส่วนของวันที่ที่กำหนดหรือไม่ หรืออย่างอื่น?
Chris J

1
สำหรับการอภิปรายมีสุขภาพดีเกี่ยวกับเรื่องนี้ (รวมทั้งเหตุผลที่มันไม่ดีที่จะรักษาDATETIMEค่าเช่นสตริงและทำไมมันจะไม่ดีที่จะใช้BETWEENหรือ>= AND <=) ดูบล็อกนี้โดยแอรอนเบอร์ทรานด์
Aaron Bertrand

คำถามของคุณมี5คะแนนโหวตสำหรับแท็กlike-operator เป็นอย่างน้อย ฉันขอให้คุณแนะนำsql-likeเป็นคำพ้องความหมายได้ไหม
Kermit

คำตอบ:


138

คุณสามารถใช้ฟังก์ชัน DATEPART ()

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

ฉันพบว่าวิธีนี้อ่านง่ายเนื่องจากไม่สนใจองค์ประกอบของเวลาและคุณไม่จำเป็นต้องใช้วันที่ของวันถัดไปเพื่อ จำกัด การเลือกของคุณ คุณสามารถไปที่ความละเอียดมากขึ้นหรือน้อยลงได้โดยการเพิ่มส่วนคำสั่งพิเศษโดยใช้รหัส DatePart ที่เหมาะสมเช่น

AND    DATEPART(hh, register_date) = 12)

เพื่อรับบันทึกที่ทำระหว่าง 12 ถึง 1

ดูเอกสาร MSDN DATEPARTสำหรับรายการอาร์กิวเมนต์ที่ถูกต้องทั้งหมด


หากมีดัชนีใน register_date สิ่งนี้จะเพิกเฉยต่อดัชนีและประสิทธิภาพจะได้รับผลกระทบ อาจจะค่อนข้างแย่
Chris J

โอเค แต่จะหลีกเลี่ยงปัญหาในการใช้สตริงที่เทียบเท่าของวันถัดจากวันที่ที่เป็นปัญหาซึ่งจะแนะนำในคำตอบบางส่วนที่นี่ ยุ่งยากตรงที่วันที่เป็นปัญหาคือสิ้นเดือนหรือปี
Ralph Lavelle

60

ไม่มีการสนับสนุนตัวดำเนินการ LIKE โดยตรงกับตัวแปร DATETIME แต่คุณสามารถส่ง DATETIME เป็น VARCHAR ได้ตลอดเวลา:

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

ตรวจสอบเอกสาร MSDNสำหรับรายการ "สไตล์" ที่มีอยู่ทั้งหมดในฟังก์ชัน CONVERT

มาร์ค


1
เห็นด้วย - แต่ OP ขอวิธีจัดการ datetime ด้วย LIKE .... แต่ฉันเห็นด้วย - ควรจัดการวันที่ด้วยช่วงเช่น> = และ <= หรือระหว่าง - วิธีการที่ดีกว่ามาก
marc_s

ขอบคุณทุกคน. ขออภัยฉันเพิ่งเป็นมือใหม่สำหรับ SQL
Paisal

1
โปรดทราบว่า MSSQL 2012 (ฉันเดาว่าเวอร์ชันเก่ากว่าด้วย) จะแปลงวันที่และเวลาเป็น varchar เป็น '2014-01-06T16: 18: 00.045' ดังนั้นโปรดจำไว้ว่าหากคุณพยายามจับคู่ชั่วโมง / นาทีด้วย
balint

ปัญหาเดียวที่ฉันมีกับการเลือก sql ด้านบนคือ: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu

10

หากคุณทำเช่นนั้นคุณกำลังบังคับให้ทำการแปลงสตริง จะเป็นการดีกว่าหากสร้างช่วงวันที่เริ่มต้น / สิ้นสุดและใช้:

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

สิ่งนี้จะช่วยให้สามารถใช้ดัชนี (หากมีอยู่register_date) แทนที่จะสแกนตาราง


ขอบคุณ. ขออภัยฉันเพิ่งเป็นมือใหม่สำหรับ SQL
Paisal

8

คุณสามารถใช้ CONVERT เพื่อรับวันที่ในรูปแบบข้อความ หากคุณแปลงเป็น varchar (10) คุณสามารถใช้ = แทน like:

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

หรือคุณสามารถใช้วันที่ขอบเขตบนและล่างโดยมีข้อได้เปรียบเพิ่มเติมที่สามารถใช้ดัชนีได้:

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

ฉันคิดว่ามีการพิมพ์ผิดในประโยคที่ควรเป็น"where '2009-10-10'> = register_date"
Vishwanath Dalvi

@mr_eclair: อย่าคิดอย่างนั้นนั่นจะรวมถึงทุกวันก่อนวันที่ 11 ต.ค.
Andomar

8

น่าเสียดายที่ไม่สามารถเปรียบเทียบวันที่และเวลากับ varchar โดยใช้ 'LIKE' ได้ แต่ผลลัพธ์ที่ต้องการเป็นไปได้ในอีกทางหนึ่ง

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

3

คุณยังสามารถใช้การแปลงเพื่อทำให้วันที่ค้นหาได้โดยใช้ LIKE ตัวอย่างเช่น,

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

2

ตัวLIKEดำเนินการไม่ทำงานกับส่วนวันที่เช่นเดือนหรือวันที่ แต่ตัวDATEPARTดำเนินการทำ

คำสั่งเพื่อค้นหาบัญชีทั้งหมดที่มีวันที่เปิดอยู่ในวันที่ 1:

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

* หล่อOpenDtเพราะมูลค่าของมันอยู่ในและไม่เพียงDATETIMEDATE



1

มีการครอบคลุมที่ไม่สม่ำเสมอของตัวดำเนินการ LIKE สำหรับวันที่ใน SQL Server ใช้งานได้โดยใช้รูปแบบวันที่แบบอเมริกันเท่านั้น เป็นตัวอย่างที่คุณสามารถลอง:

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

ฉันได้ทดสอบสิ่งนี้ใน SQL Server 2005 และใช้งานได้ แต่คุณจะต้องลองใช้ชุดค่าผสมต่างๆ สิ่งแปลก ๆ ที่ฉันสังเกตเห็นคือ:

  • ดูเหมือนว่าคุณจะได้รับทั้งหมดหรือไม่ได้อะไรเลยสำหรับช่องย่อยที่แตกต่างกันภายในวันที่เช่นหากคุณค้นหา "apr 2%" คุณจะได้อะไรก็ตามในช่วงวันที่ 20 เท่านั้นซึ่งจะละเว้นช่องที่ 2

  • การใช้เครื่องหมายขีดล่าง '_' ตัวเดียวเพื่อแทนอักขระ (ตัวแทน) ตัวเดียวไม่ได้ผลทั้งหมดเช่นWHERE mydate LIKE 'oct _ 2010%'จะไม่ส่งคืนวันที่ทั้งหมดก่อนวันที่ 10 แต่จะไม่คืนค่าใด ๆ เลยในความเป็นจริง!

  • รูปแบบเป็นแบบอเมริกันที่เข้มงวด: ' mmm dd yyyy hh:mm'

ฉันพบว่ามันยากที่จะทำให้ขั้นตอนการกดไลค์เป็นวินาทีได้ยากดังนั้นหากใครต้องการใช้เวลาต่อไปนี้เป็นแขกของฉัน!

หวังว่านี่จะช่วยได้


1

ฉันช้าไปหน่อยสำหรับเธรดนี้ แต่ในความเป็นจริงมีการสนับสนุนโดยตรงสำหรับตัวดำเนินการ like ในเซิร์ฟเวอร์ MS SQL

ตามที่ระบุไว้ในวิธีใช้ LIKE หากประเภทข้อมูลไม่ใช่สตริงจะมีการพยายามแปลงเป็นสตริง และตามที่ระบุไว้ในเอกสาร cast \ convert:

การแปลงวันที่และเวลาเริ่มต้นเป็นสตริงคือประเภท 0 (, 100) ซึ่งเป็น mon dd yyyy hh: miAM (หรือ PM)

หากคุณมีวันที่เช่นนี้ในฐานข้อมูล:

2015-06-01 11:52:59.057

และคุณทำแบบสอบถามเช่นนี้:

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'

คุณได้แถวนั้น

อย่างไรก็ตามรูปแบบวันที่นี้แสดงให้เห็นว่าเป็นDateTime2จากนั้นเอกสารจะระบุว่า:

21 หรือ 121 - ODBC canonical (พร้อมมิลลิวินาที) เป็นค่าเริ่มต้นสำหรับเวลาวันที่ datetime2 และ datetimeoffset - yyyy-mm-dd hh: mi: ss.mmm (24 ชม.)

ที่ทำให้ง่ายขึ้นและคุณสามารถใช้:

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

และรับบันทึกใบแจ้งหนี้ นี่คือรหัสสาธิต:

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 โดยไม่มีการแปลงเป็นสตริงเป็นปัญหาเสมอ การรับแต่ละส่วนของวันที่เป็นส่วนเกิน (ซึ่งไม่น่าจะใช้ดัชนี) อาจเป็นวิธีที่ดีกว่าเมื่อคุณไม่ใช้การแปลงสตริงคือใช้การตรวจสอบช่วง กล่าวคือ:

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

0

ฉันแก้ปัญหาด้วยวิธีนั้น ขอบคุณสำหรับคำแนะนำสำหรับการปรับปรุง ตัวอย่างใน 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 + "%'";
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.