出于兴趣我有一个相当基本的问题。在T-SQL(SSMS等)中,在where语句中使用dd-mm-yyyy
和yyyy-mm-dd
之间的区别是“幕后”。
例如,这两个查询给我不同的结果
select * from DB..table where application_date > '01-01-2019' and application_date < '01-06-2019' order by app_ID;
select * from DB..table where application_date > '2019-01-01' and application_date < '2019-06-01' order by app_ID;
似乎第一个是第二个的子集。 为了进行比较,第一个给了我83条记录,第二个给了我11000多个变化。
如果有人能启发我,这将很有趣。
答案 0 :(得分:5)
datetime
值的字符串表示形式取决于区域性。
例如,在美国,字符串表示格式为MM/dd/yyyy
,而在英国则为dd/MM/yyyy
。
这意味着SQL Server将根据区域性设置将字符串文字转换为datetime
,具体地说,它是DATEFORMAT
-除非字符串表示格式符合ISO 8601标准-要么是{{ 1}}或yyyy-MM-ddTHH:mm:ss
。
但是,yyyyMMddTHHmmss
数据类型存在一个鲜为人知的错误(或功能),当从格式为DateTime
的字符串转换仅日期的值时,转换仍取决于区域性设置-从备用ISO 8601格式yyyy-MM-dd
进行转换时,对于所有日期时间数据类型都是绝对安全的。
这可能是因为该格式不是ISO 8601独有的-它还是ODBC规范格式的一部分-yyyyMMdd
-与ISO 8601几乎相同,只是带有空格而不是T日期部分和时间部分之间的分隔符。
此错误仅存在于yyyy-MM-dd HH:mm:ss
数据类型中,这是为什么您应该始终喜欢使用更新和改进的DateTime
数据类型的几个原因之一。
有关更多信息,请阅读Date conversion and culture: Difference between DATE and DATETIME.
TL; DR;
与DateTime2
一起使用的唯一安全的字符串表示日期格式是datetime
。
所有其他格式的转换都取决于区域性,并且可能会产生错误或更糟糕的结果-错误的结果。
要点:
yyyyMMdd
比DateTime2
更合适。datetime
的字符串表示形式。datetime
的字符串表示形式时,请始终使用ISO 8601格式之一-datetime
或yyyy-MM-ddTHH:mm:ss
yyyyMMddTHHmmss
和日期的字符串表示形式时,总是使用DateTime
。答案 1 :(得分:4)
文字'01-06-2019'
实际上被解释为2019-01-06
,与第二个查询使用的2019-06-01
完全不一样。
您可以阅读SQL Server的documentation,其中涵盖了受支持的日期文字格式。但是总的来说,请尝试使用ISO日期格式,几乎每个SQL数据库都支持ISO日期格式。因此,查询的第二个版本是您应该始终尝试使用的版本。