Làm cách nào để truy vấn trường DATETIME chỉ sử dụng ngày trong Microsoft SQL Server?


88

Tôi có một bảng TEST với một DATETIMEtrường, như sau:

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

Tôi cần một truy vấn trả lại hàng này và mọi hàng có ngày 19/03/2014, bất kể thời gian là gì. Tôi đã thử sử dụng

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

Nhưng nó không trả về hàng. Cách duy nhất để làm cho nó hoạt động mà tôi tìm thấy là cung cấp phần thời gian của ngày:

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

Câu trả lời:


126

phạm vi sử dụng hoặc hàm DateDiff

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

hoặc là

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

Các tùy chọn khác là:

  1. Nếu bạn có quyền kiểm soát lược đồ cơ sở dữ liệu và bạn không cần dữ liệu thời gian, hãy lấy nó ra.

  2. hoặc, nếu bạn phải giữ nó, hãy thêm thuộc tính cột được tính toán có phần thời gian của giá trị ngày bị loại bỏ ...

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

hoặc trong các phiên bản mới hơn của SQL Server ...

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

sau đó, bạn có thể viết truy vấn của mình đơn giản như sau:

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

Ok, cách này hoạt động, nhưng tôi đã tự hỏi liệu có cách nào dễ dàng hơn không.
delphirules

Chà, cách duy nhất dễ dàng hơn là không đưa dữ liệu thời gian vào cơ sở dữ liệu ngay từ đầu ... hoặc tạo một thuộc tính được tính toán để loại bỏ phần thời gian và sử dụng nó ... Tôi đã thêm cả hai tùy chọn vào câu trả lời của mình.
Charles Bretana

Tôi lo ngại rằng phương thức DATEDIFF sẽ trả về true (không thể chọn được) cho những ngày như 19/4/2014 hoặc 19/3/2015, vì phần 'ngày' của những ngày đó giống nhau (và tôi đã xem báo cáo ở những nơi khác rằng nó sẽ hành động theo cách này), nhưng tôi đã thử nghiệm nó với cơ sở dữ liệu và nó có vẻ hoạt động chính xác.
mono código

Có, bởi vì DateDiff()hàm, trong tất cả các biến thể của nó, tính toán và trả về số lượng ranh giới ngày phải vượt qua để đưa frlom ngày này sang ngày kia. Đây là lý do tại sao DateDiff(day, '1Jan2016', '31Dec2017 23:259:59')DateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') cả hai đều quay trở lại 1.
Charles Bretana

55

Câu trả lời đơn giản;

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

Mặc dù đây là một câu trả lời hợp lệ, tôi muốn chỉ ra rằng việc đặt trường ngày đánh giá đằng sau bất kỳ chức năng nào sẽ dẫn đến các vấn đề về hiệu suất. Bất kỳ chỉ số vào ngày sẽ là vô ích và động cơ sẽ cần phải đánh giá từng hàng
jean


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

Đây là một câu trả lời thực sự tồi tệ . Vì hai lý do.

1. Điều gì xảy ra với những thời điểm như 23.59.59.700 v.v ... Có những thời điểm lớn hơn 23:59:59 và ngày hôm sau.

2. Hành vi phụ thuộc vào kiểu dữ liệu. Truy vấn hoạt động khác nhau đối với các loại datetime / date / datetime2.

Thử nghiệm với 23: 59: 59.999 thậm chí còn tệ hơn vì tùy thuộc vào loại dữ liệu mà bạn nhận được các vòng làm tròn khác nhau.

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'))

- Đối với ngày giá trị là 'cắt nhỏ'. - Đối với datetime, giá trị được làm tròn đến ngày tiếp theo. (Giá trị gần nhất). - Đối với datetime2, giá trị là chính xác.


7

Điều này phù hợp với tôi đối với máy chủ MS SQL:

select * from test
where 
year(date) = 2015
and month(date) = 10
and day(date)= 28 ;

1

Thử đi

 select * from test where Convert(varchar, date,111)= '03/19/2014'

1

bạn có thể thử cái này

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

1
Cảm ơn bạn, nhưng tôi nghĩ giải pháp đơn giản hơn sẽ là so sánh với thời gian, giống như giải pháp trước đó.
delphirules

0

Bạn có thể sử dụng phương pháp này để cắt bớt phần thời gian:

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

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
Vui lòng thêm một số giải thích cho câu trả lời của bạn!
ρss

Đây không phải làm việc vì '2015/10/28 00: 00,001' khác với '2015/10/28'
PedroC88

0

Đơn giản chỉ cần sử dụng điều này trong WHEREmệnh đề của bạn .

Phần "Ngày gửi" bên dưới là tên cột, vì vậy hãy chèn cột của riêng bạn.

Điều này sẽ chỉ trả về phần "Năm" của kết quả, bỏ qua phút, v.v.

Where datepart(year, SubmitDate) = '2017'

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

"col1" là tên của cột có ngày giờ
<tên của cột> ở đây bạn có thể đổi tên theo ý muốn


0
select *
  from invoice
 where TRUNC(created_date) <=TRUNC(to_date('04-MAR-18 15:00:00','dd-mon-yy hh24:mi:ss'));

0

Có một vấn đề với ngày tháng và ngôn ngữ và cách để tránh nó là yêu cầu ngày tháng với định dạng YYYYMMDD này.

Cách này bên dưới chắc sẽ nhanh nhất theo link bên dưới. Tôi đã kiểm tra trong SQL Server 2012 và tôi đồng ý với liên kết.

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

0

dùng cái này

select * from TableName where DateTimeField > date() and  DateTimeField < date() + 1

-1

Kiểm tra truy vấn này.

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

Tôi nghĩ đây là cú pháp Oracle, không hoạt động ở máy chủ sql
ceinmart

-2
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018'  and  DATEPART(day,[TIMESTAMP]) = '16' and  DATEPART(month,[TIMESTAMP]) = '11'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.