在 SQL 中查询比较日期

Posted

技术标签:

【中文标题】在 SQL 中查询比较日期【英文标题】:Query comparing dates in SQL 【发布时间】:2013-11-24 07:26:51 【问题描述】:

我有一张表,上面的日期都发生在 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

【问题讨论】:

您将日期与字符串进行比较,而不是日期与日期进行比较 也许它认为2013-04-12?是 4 月 12 日吗?或者created_date是一个字符串而不是一个日期? 查看 T-SQL 手册上的 Cast & Convert 并为您的语言环境使用适当的转换 完全不需要强制转换,使用不变的格式'20130412' 与其发送带有日期的字符串,不如尝试创建参数化查询并将日期作为日期类型的参数传递。顺便说一句,您使用的是什么版本的 SQL Server? DATE 是在 SQL Server 2008 中添加的。 【参考方案1】:

不要使用含义取决于当地文化的“2013-04-12”,而是使用被识别为文化不变格式的“20130412”。

如果您想与 12 月 4 日th 进行比较,您应该写 '20131204'。如果你想和 4 月 12 日th 比较,你应该写 '20130412'。

SQL Server 文档中的文章Write International Transact-SQL Statements 解释了如何编写文化不变的语句:

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

编辑

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

更新

要在文字中使用 ISO 8601 格式,必须指定所有元素。引用from the ISO 8601 section of datetime's documentation

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

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

【讨论】:

@andy 不完全是,ISO8601 格式 包括 时间元素。或as the docs say、To use the ISO 8601 format, you must specify each element in the format. This also includes the T 抱歉不清楚,我的意思是 ISO8601 按照您描述的方式定义顺序:YYYY-MM-DD 或简称 YYYYMMDD。但是,正如文档还指出的那样:“日期时间不符合 ANSI 或 ISO 8601。”。 ISO 本身不需要时间部分。 您所指的内容并没有改变YYYY-MM-DD 被识别为 ISO 8601 的事实。时间部分必需的。如果您愿意,可以称其为 T-SQL 的怪异,或者不完整的实现。甚至可能是从 Sybase 继承下来的【参考方案2】:

日期格式为 yyyy-mm-dd。 所以上面的查询是寻找早于 12Apr2013 的记录

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

【讨论】:

【参考方案3】:

这样试试

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

【讨论】:

文化特定格式。是 4 月 12 日还是 12 月 4 日?破折号分隔的格式不是国际格式 那么当您需要存储来自国际客户的数据时会发生什么?或者日期来自遵循用户文化的网络浏览器?指南的存在是有原因的,只要不使用错误的格式,就可以避免所有错误 @Nithesh 这是 4 月 12 日返回 @PanagiotisKanavos 破折号分隔格式自 ISO 8601 于 1988 年发布以来的国际格式。不鼓励使用其他格式和 ridiculed。即使是您发布的文章"Write International Transact-SQL Statements" 也从未将“yyyymmdd”标识为任何类型的“国际”标准。 在日期前后添加单引号为我解决了这个问题。使用格式 2/19/2015。更改为“2/19/2015”并开始工作。感谢您的简单想法。【参考方案4】:

请尝试以下查询

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

【讨论】:

【参考方案5】:

您输入&lt;=,它也会捕获给定的日期。您只能将其替换为 &lt;

【讨论】:

【参考方案6】:

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

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

这种转换也适用于使用GetDate()函数

【讨论】:

【参考方案7】:

尝试在日期前后使用“#”,并确保您的系统日期格式。也许“YYYYMMDD O YYYY-MM-DD O MM-DD-YYYY O USING '/ O \'”

例如:

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

【讨论】:

【参考方案8】:

将它们转换为相同格式的日期,然后您可以进行比较。像这样写:

where convert(date, created_date,102) <= convert(date,                                  /*102 is ANSI format*/
                                                    substring('2013-04-12',1,4) + '.' + /*year*/
                                                    substring('2013-04-12',9,2) + '.' + /*month*/
                                                    substring('2013-04-12',6,2)         /*day*/
                                                ,102)

【讨论】:

【参考方案9】:

你也可以使用 to_char(column_name, 'YYYY-MM-DD) 来改变格式

【讨论】:

【参考方案10】:

以下查询可用于查找 2013 年 11 月的记录。

Select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where Month(created_date) = 11 and Year(created_date) = 2013

【讨论】:

以上是关于在 SQL 中查询比较日期的主要内容,如果未能解决你的问题,请参考以下文章

sql语句中怎样比较两个日期的大小???

sqlserver 中 怎么用比较日期进行查询?

sql语句中日期时间类型怎么比较

SQL 中怎么根据出生日期算出年龄 然后用年龄查询

如何在 EF 查询中执行日期比较?

具有动态日期比较的 JCR SQL2 查询