在SQL中查询比较日期


83

我有一张桌子,上面列出了所有发生在11月的日期。我写了这个查询

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
created_date <= '2013-04-12'

此查询应返回11月(11月)中发生的所有事情,因为它发生日期“ 2013-04-12”(12月)之前

但它只是返回的可用日期是发生在天,比04较少(2013- 04 -12)

难道只是比较一天的一部分?而不是整个日期?

如何解决这个问题?

Created_date的类型为date

日期格式默认为yyyy-dd-MM


1
您正在比较日期和字符串,而不是日期和日期
Panagiotis Kanavos

4
也许是这样想的2013-04-12?是4月12日?也许created_date是字符串而不是日期?
jpw

查看T-SQL上的Cast&Convert手册,并针对您的语言环境使用适当的转换
Steve

3
根本不需要强制转换,只需使用不变格式“ 20130412”
Panagiotis Kanavos 2013年

1
而不是发送带有日期的字符串,而是尝试创建参数化查询并将日期作为日期类型的参数传递。顺便说一句,您正在使用哪个版本的SQL Server?在SQL Server中加入日期2008年
帕纳约蒂斯Kanavos

Answers:


81

代替含义取决于当地文化的“ 2013-04-12”,而应使用公认的文化不变格式“ 20130412”。

如果要与12月4进行比较,则应输入'20131204'。如果您想与4月12进行比较,则应输入'20130412'。

SQL Server文档中的“编写国际Transact-SQL语句”一文介绍了如何编写区域性不变的语句:

使用其他API或Transact-SQL脚本,存储过程和触发器的应用程序应使用不分隔的数字字符串。例如,yyyymmdd为19980924。

编辑

由于您使用的是ADO,因此最好的选择是对查询进行参数化并将日期值作为日期参数传递。这样,您就可以完全避免格式问题,并且还可以获得参数化查询的性能优势。

更新

要在文字中使用ISO 8601格式,必须指定所有元素。引用日期时间文档的ISO 8601部分

要使用ISO 8601格式,必须指定格式中的每个元素。这还包括以格式显示的T,冒号(:)和句点(。)。

...第二部分的分数是可选的。时间部分以24小时格式指定。


@andy不完全是,ISO8601格式包含时间元素。或如文档所说To use the ISO 8601 format, you must specify each element in the format. This also includes the T
Panagiotis Kanavos 2015年

1
抱歉,不清楚,我的意思是ISO8601只是按照您描述的方式定义了顺序:YYYY-MM-DD或简称YYYYMMDD。但是,文档也指出:“ datetime不符合ANSI或ISO8601。”。ISO本身不需要时间部分。
andy 2015年

什么你是指不改变的事实YYYY-MM-DD没有公认的ISO 8601部分的时间必需的。如果愿意的话,称它为T-SQL的怪异之处,或者说实现不完整。甚至有可能是从Sybase继承而来的
Panagiotis Kanavos

31

这样尝试

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
created_date <= '2013-12-04'

6
特定于文化的格式。是4月12日还是12月4日?破折号分隔的格式不是国际格式
Panagiotis Kanavos

1
那么,当您需要存储来自国际客户的数据时会发生什么呢?还是日期来自遵循用户文化的网络浏览器?该准则的存在是有原因的,只需不使用错误的格式,就可以避免所有错误
Panagiotis Kanavos

1
@Nithesh这将在4月12
HelpASisterOut

17
@PanagiotisKanavos短划线分隔格式自1988年ISO 8601发布以来的国际格式。不鼓励使用其他格式,并且嘲笑其他格式。即使您发表的文章“写国际Transact-SQL语句”也从未将'yyyymmdd'标识为任何类型的“国际”标准。
杰西·韦伯

2
在日期前后添加单引号可以解决此问题。使用的格式为2015年2月19日。更改为“ 2015年2月19日”并开始工作。感谢您的简单想法。
伊桑·特克

9

如果您仅将其与日期值进行比较,则将其转换为日期(而不是datetime)将起作用

select id,numbers_from,created_date,amount_numbers,SMS_text 
 from Test_Table
 where 
 created_date <= convert(date,'2013-04-12',102)

在使用GetDate()函数期间,此转换也适用


4

您放了<=,它也会赶上给定的日期。您只能将其替换<


2

请尝试以下查询

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
convert(datetime, convert(varchar(10), created_date, 102))  <= convert(datetime,'2013-04-12')

0

日期格式为yyyy-mm-dd。因此,上面的查询正在查找早于2013年4月12日的记录

建议您通过将日期字符串设置为'2013-04-30'进行快速检查,如果没有SQL错误,则将日期格式确认为yyyy-mm-dd。


0

尝试在日期前后使用“#”,并确保使用系统日期格式。可能是“ YYYYMMDD O YYYY-MM-DD O MM-DD-YYYY O使用'/ O \'“

例如:

 select id,numbers_from,created_date,amount_numbers,SMS_text 
 from Test_Table
 where 
 created_date <= #2013-04-12#
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.