วิธีการสอบถามฟิลด์ DATETIME โดยใช้วันที่เท่านั้นใน Microsoft SQL Server


90

ฉันมีตาราง TEST พร้อมDATETIMEฟิลด์ดังนี้:

ID NAME DATE
1 TESTING 2014-03-19 20:05:20.000

สิ่งที่ฉันต้องการคำค้นหาที่ส่งคืนแถวนี้และทุกแถวที่มีวันที่ 03/19/2014 ไม่ว่าเวลาจะเป็นอย่างไร ฉันลองใช้

select * from test where date = '03/19/2014';

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

select * from test where date = '03/19/2014 20:03:02.000';

คำตอบ:


129

ใช้ช่วงหรือฟังก์ชัน DateDiff

 select * from test 
 where date between '03/19/2014' and '03/19/2014 23:59:59'

หรือ

 select * from test 
 where datediff(day, date, '03/19/2014') = 0

ตัวเลือกอื่น ๆ ได้แก่ :

  1. หากคุณสามารถควบคุมสคีมาฐานข้อมูลและคุณไม่ต้องการข้อมูลเวลาให้นำออก

  2. หรือถ้าคุณต้องเก็บไว้ให้เพิ่มแอตทริบิวต์คอลัมน์ที่คำนวณแล้วซึ่งมีส่วนเวลาของค่าวันที่ถูกขีดฆ่า ...

Alter table Test Add DateOnly As DateAdd(day, datediff(day, 0, date), 0)

หรือในเวอร์ชันล่าสุดของ SQL Server ...

Alter table Test Add DateOnly As Cast(DateAdd(day, datediff(day, 0, date), 0) as Date)

จากนั้นคุณสามารถเขียนแบบสอบถามของคุณได้ง่ายๆดังนี้:

select * from test 
where DateOnly = '03/19/2014'

โอเคได้ผล แต่ฉันสงสัยว่ามีวิธีที่ง่ายกว่านี้ไหม
delphirules

วิธีเดียวที่ง่ายกว่านั้นคืออย่าใส่ข้อมูลเวลาลงในฐานข้อมูลตั้งแต่แรก ... หรือสร้างแอตทริบิวต์ที่คำนวณซึ่งตัดส่วนของเวลาออกและใช้มัน ... ฉันเพิ่มทั้งสองตัวเลือกในคำตอบของฉัน
Charles Bretana

ฉันกังวลว่าเมธอด DATEDIFF จะส่งคืนจริง (อย่างไม่สมควร) สำหรับวันที่เช่น 19/4/2557 หรือ 19/3/2558 เนื่องจากส่วน 'วัน' ของวันที่เหล่านั้นเหมือนกัน (และฉันเคยเห็นรายงานจากที่อื่นว่าจะ ดำเนินการในลักษณะนี้) แต่ฉันทดสอบกับฐานข้อมูลและดูเหมือนว่าจะทำงานได้อย่างถูกต้อง
mono código

ใช่เนื่องจากDateDiff()ฟังก์ชันในรูปแบบทั้งหมดจะคำนวณและส่งกลับจำนวนของขอบเขตวันที่ที่ต้องข้ามเพื่อรับวันที่หนึ่งไปยังอีกวันหนึ่ง นี่คือเหตุผลDateDiff(day, '1Jan2016', '31Dec2017 23:259:59')และทั้งสองกลับมาDateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') 1
Charles Bretana

56

คำตอบง่ายๆ

select * from test where cast ([date] as date) = '03/19/2014';

แม้ว่านี่จะเป็นคำตอบที่ถูกต้อง แต่ฉันต้องการชี้ให้เห็นว่าการกำหนดฟิลด์วันที่ไว้เบื้องหลังฟังก์ชันใด ๆ จะทำให้เกิดปัญหาด้านประสิทธิภาพ ดัชนีใด ๆ ในวันที่จะไร้ประโยชน์และเครื่องยนต์จะต้องประเมินแต่ละแถว
ยีน

21

ฉันใช้ MySQL 5.6 และมีฟังก์ชัน DATE เพื่อแยกเฉพาะส่วนวันที่จากวันที่เวลา ดังนั้นวิธีง่ายๆสำหรับคำถามคือ -

 select * from test where DATE(date) = '2014-03-19';

http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html


2
คำถามเกี่ยวกับเซิร์ฟเวอร์ sql
Kiquenet

7
select * from test 
where date between '03/19/2014' and '03/19/2014 23:59:59'

นี่เป็นคำตอบที่ไม่ดีจริงๆ ด้วยเหตุผลสองประการ

1. เกิดอะไรขึ้นกับเวลาเช่น 23.59.59.700 เป็นต้นมีครั้งใหญ่กว่า 23:59:59 น. และในวันถัดไป

2. ลักษณะการทำงานขึ้นอยู่กับประเภทข้อมูล แบบสอบถามทำงานแตกต่างกันสำหรับชนิด datetime / date / datetime2

การทดสอบด้วย 23: 59: 59.999 ยิ่งทำให้แย่ลงเพราะขึ้นอยู่กับประเภทข้อมูลที่คุณได้รับการปัดเศษที่แตกต่างกัน

select convert (varchar(40),convert(date      , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime  , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime2 , '2014-03-19 23:59:59.999'))

- สำหรับวันที่ค่าคือ 'สับ' - สำหรับวันที่และเวลาค่าจะปัดเศษขึ้นเป็นวันถัดไป (ค่าที่ใกล้ที่สุด). - สำหรับ datetime2 ค่าจะแม่นยำ




1

คุณสามารถลองสิ่งนี้

select * from test where DATEADD(dd, 0, DATEDIFF(dd, 0, date)) = '03/19/2014';

1
ขอบคุณ แต่ฉันคิดว่าวิธีแก้ปัญหาที่ง่ายกว่านั้นจะเป็นการเปรียบเทียบกับเวลาเช่นเดียวกับวิธีแก้ปัญหาก่อนหน้านี้
delphirules


0
-- Reverse the date format
-- this false:
    select * from test where date = '28/10/2015'
-- this true:
    select * from test where date = '2015/10/28'

1
โปรดเพิ่มคำอธิบายในคำตอบของคุณ!
58

สิ่งนี้ใช้ไม่ได้เพราะ '2015/10/28 00: 00.001' แตกต่างจาก '2015/10/28'
PedroC88

0

เพียงใช้สิ่งนี้ในWHEREประโยคของคุณ

ส่วน "SubmitDate" ด้านล่างคือชื่อคอลัมน์ดังนั้นให้ใส่ชื่อคอลัมน์ของคุณเอง

สิ่งนี้จะส่งคืนเฉพาะส่วน "ปี" ของผลลัพธ์โดยละเว้นนาทีเป็นต้น

Where datepart(year, SubmitDate) = '2017'

0
select *, cast ([col1] as date) <name of the column> from test where date = 'mm/dd/yyyy'

"col1" คือชื่อคอลัมน์ที่มีวันที่และเวลา
<ชื่อคอลัมน์> ที่นี่คุณสามารถเปลี่ยนชื่อได้ตามต้องการ



0

มีปัญหากับวันที่และภาษาและวิธีหลีกเลี่ยงคือขอวันที่ด้วยรูปแบบนี้ YYYYMMDD

ทางด้านล่างนี้น่าจะเร็วที่สุดตามลิงค์ด้านล่างนี้ ฉันตรวจสอบใน SQL Server 2012 และฉันเห็นด้วยกับลิงก์

select * from test where date >= '20141903' AND date < DATEADD(DAY, 1, '20141903');


-1

ทดสอบคำค้นหานี้

SELECT *,DATE(chat_reg_date) AS is_date,TIME(chat_reg_time) AS is_time FROM chat WHERE chat_inbox_key='$chat_key' 
                         ORDER BY is_date DESC, is_time DESC

-1
select * from invoice where TRANS_DATE_D>= to_date  ('20170831115959','YYYYMMDDHH24MISS')
and TRANS_DATE_D<= to_date  ('20171031115959','YYYYMMDDHH24MISS');

ฉันคิดว่านี่เป็นไวยากรณ์ของ Oracle ไม่ทำงานที่เซิร์ฟเวอร์ sql
ceinmart

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