如何在Microsoft SQL Server中仅使用日期查询DATETIME字段?


88

我有一个表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';

Answers:


126

使用范围或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 2014年

好吧,唯一更简单的方法是不要首先将时间数据放入数据库中……或者创建一个可以去除时间部分并使用它的计算属性……我在答案中都添加了这两个选项。
查尔斯·布雷塔纳2014年

我担心DATEDIFF方法会在4/19/2014或3/19/2015之类的日期返回true(不希望有的结果),因为这些日期的“天”部分是相同的(并且我在其他地方看到过报告说它将采取这种方式),但是我针对数据库进行了测试,它似乎可以正常运行。
monocódigo16年

是的,因为该DateDiff()函数在其所有变体中都会计算并返回必须跨越的日期边界数才能将一个日期转换为另一个日期。这就是为什么DateDiff(day, '1Jan2016', '31Dec2017 23:259:59')DateDiff(day, '31Dec2016 23:259:59', '1Jan2017 ') 这两个回报1
Charles Bretana

55

简单的答案;

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

虽然这是一个有效的答案,但我想指出的是,将date字段求值放在任何函数之后会导致性能问题。日期中的任何索引都是无用的,引擎将需要评估每一行
jean


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 Convert(varchar, date,111)= '03/19/2014'

1

你可以试试这个

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

1
谢谢,但是我认为更简单的解决方案将是与时间的比较,就像之前的解决方案一样。
delphirules 2014年

0

您可以使用这种方法来截断时间部分:

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
请为您的答案添加一些解释!
ρss

这不起作用,因为“ 2015/10/28 00:00.001”与“ 2015/10/28”不同
PedroC88 2016年

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

0

日期和语言存在问题,避免这种情况的方法是要求使用YYYYMMDD格式的日期。

根据下面的链接,下面的这种方式应该是最快的。我检查了SQL Server 2012,并同意该链接。

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

0

用这个

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

-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 Server上
不起作用

-2
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018'  and  DATEPART(day,[TIMESTAMP]) = '16' and  DATEPART(month,[TIMESTAMP]) = '11'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.