MySQL เปรียบเทียบสตริง DATE กับสตริงจากฟิลด์ DATETIME


93

ฉันมีคำถาม: เป็นไปได้ไหมที่จะเลือกจากฐานข้อมูล MySQL โดยเปรียบเทียบสตริง DATE "2010-04-29" หนึ่งสตริงกับสตริงที่จัดเก็บเป็น DATETIME (2010-04-29 10:00 น.)

ฉันมีตัวเลือกวันที่หนึ่งที่กรองข้อมูลและฉันต้องการสอบถามตารางตามช่อง DATETIME ดังนี้:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... และฉันต้องการรับแถวที่มีค่า DATETIME เป็น "2010-04-29 10:00"

ข้อเสนอแนะใด ๆ ? ขอบคุณ.

คำตอบ:


163

ใช้สิ่งต่อไปนี้:

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

เพื่อการอ้างอิงฉันมีตารางบันทึก 2 ล้านตารางฉันเรียกใช้แบบสอบถามที่คล้ายกัน คำตอบของสลิลใช้เวลา 4.48 วินาทีข้างต้นใช้เวลา 2.25 วินาที

ดังนั้นถ้าโต๊ะใหญ่ฉันอยากจะแนะนำสิ่งนี้มากกว่า


8
คำตอบแรกช้ามากเพราะต้องจัดรูปแบบวันที่และเวลาเป็นสตริงก่อนการเปรียบเทียบ ของคุณดีกว่าเพราะเปรียบเทียบเฉพาะส่วนวันที่จากฟิลด์โดยตรง แต่ยังใช้ดัชนีไม่ได้ (ทดสอบบน mysql 5.1)
Marki555

1
หากประสิทธิภาพเป็นปัญหาคุณควรพิจารณาจัดเก็บส่วนวันที่และเวลาแยกกันเพื่อให้สามารถวาง INDEX ไว้ในส่วนวันที่ได้
Thijs Riezebeek

1
แบบสอบถามนี้จะไม่สามารถใช้ดัชนีได้หากstartTimeมีการจัดทำดัชนี
Zamrony P.Juhara

43

หากคุณต้องการเลือกแถวทั้งหมดที่ส่วน DATE ของคอลัมน์ DATETIME ตรงกับตัวอักษรบางตัวคุณจะไม่สามารถทำได้:

WHERE startTime = '2010-04-29'

เนื่องจาก MySQL ไม่สามารถเปรียบเทียบ DATE และ DATETIME ได้โดยตรง สิ่งที่ MySQL ทำมันขยาย DATE literal ที่กำหนดด้วยเวลา '00: 00: 00 ' สภาพของคุณจึงกลายเป็น

WHERE startTime = '2010-04-29 00:00:00'

ไม่ใช่สิ่งที่คุณต้องการอย่างแน่นอน!

เงื่อนไขเป็นช่วงดังนั้นจึงควรกำหนดเป็นช่วง มีความเป็นไปได้หลายประการ:

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

มีความเป็นไปได้เล็กน้อยที่คนแรกจะผิด - เมื่อคอลัมน์ DATETIME ของคุณใช้ความละเอียดรองและมีการนัดหมายเวลา 23:59:59 น. + epsilon โดยทั่วไปฉันแนะนำให้ใช้ตัวแปรที่สอง

ตัวแปรทั้งสองสามารถใช้ดัชนีใน startTime ซึ่งจะมีความสำคัญเมื่อตารางเติบโตขึ้น


9
เวอร์ชันของเดวิดไม่ดีไม่สามารถใช้ดัชนีได้ การใช้ดัชนีคุณต้องกรองในคอลัมน์โดยตรงไม่ได้อยู่ในผลมาจากการทำงาน ( date(), year(), datediff()หรือคล้ายกันใด ๆ )
Marki555

ผมกำลังมองหาวิธีการที่ MySQL แปลงวันที่ datetime 00:00:00ขอบคุณสำหรับการล้างจะเพิ่ม ตอนนี้ผลลัพธ์ของฉันสมเหตุสมผลแล้ว
นักบัญชี

1
นี่คือวิธีการแก้ปัญหาที่ถูกต้องได้อย่างรวดเร็วเมื่อเทียบกับคำตอบอื่น ๆ ซึ่งไม่สามารถใช้ดัชนีถ้ามี
Zamrony พี Juhara

23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

หรือ

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

25
นี่เป็นแบบสอบถามที่แย่มาก หลีกเลี่ยงสิ่งนี้โดยเสียค่าใช้จ่ายทั้งหมด หากมีดัชนีใน startTime จะไม่สามารถใช้แบบสอบถามนี้ได้เนื่องจากจะใช้ฟังก์ชันกับคอลัมน์แทนที่จะใช้โดยตรง นั่นหมายความว่าแบบสอบถามใด ๆ เช่นนี้จะต้องมีการสแกนแบบเต็มตาราง บนตารางขนาดใหญ่จะหมายถึงแบบสอบถามที่ช้ามาก
steveayre

ฉันยอมรับคำตอบของเขาผิด - คำตอบที่ถูกต้องถูกโพสต์โดย David ด้านล่าง
mindplay.dk

1
โปรดใช้คำตอบจากเดวิดเพราะมันเร็วกว่า อันนี้ใช้ได้ แต่ไม่เหมาะกับความเร็ว ...
xarlymg89

1
@ CarlosAlbertoMartínezGadeaเวอร์ชันนี้ช้าเนื่องจากต้องจัดรูปแบบแต่ละค่าเป็นสตริงก่อนการเปรียบเทียบ ... เวอร์ชันของ David ไม่จำเป็นต้องใช้ แต่ยังไม่สามารถใช้ดัชนีได้ดังนั้นจึงไม่เหมาะสม ดูคำตอบจาก XL_ สำหรับเวอร์ชันที่สามารถใช้ดัชนีได้ น่าเสียดายที่ไม่มีวิธีที่ดีกว่าในการทำอย่างถูกต้องใน mysql
Marki555

1
ฉันลงคะแนนคำตอบนี้เนื่องจากแบบสอบถามไม่สามารถใช้ดัชนีได้ในขณะที่คำตอบของ @ XL_ ทำ
pedromanoel

2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

สิ่งนี้สำหรับรูปแบบวันที่และเวลาใน mysql โดยใช้DATE_FORMAT(date,format).


1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

ช่วยให้คุณสามารถแปลงค่าได้เหมือนDATEก่อนเปรียบเทียบ


0

คุณสามารถแคสต์ช่อง DATETIME เป็น DATE เป็น:

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

นี้มีประสิทธิภาพมาก


1
ไม่มันไม่มีประสิทธิภาพด้วย สิ่งนี้จะไม่สามารถใช้ดัชนีได้หากstartTimeมีการจัดทำดัชนี
Zamrony P.Juhara

-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.