Sql 我想了解以下字符串如何介于其他两个字符串之间
注意这是我的第一篇帖子:) 我正在编写一个程序,看到一些代码的行为出人意料。我知道有一些隐式数据转换,但我不明白它是如何计算为真的 我运行了下面的代码,它按照我的预期选择了“是”而不是“否” 代码使用了GETDATE()。我把它改成了今天的日期,所以如果需要的话,代码可以在另一天运行Sql 我想了解以下字符串如何介于其他两个字符串之间,sql,sql-server,tsql,Sql,Sql Server,Tsql,注意这是我的第一篇帖子:) 我正在编写一个程序,看到一些代码的行为出人意料。我知道有一些隐式数据转换,但我不明白它是如何计算为真的 我运行了下面的代码,它按照我的预期选择了“是”而不是“否” 代码使用了GETDATE()。我把它改成了今天的日期,所以如果需要的话,代码可以在另一天运行 SELECT CASE WHEN CONVERT(VARCHAR,CAST('6/14/2016' AS DATETIME),101) BETWEEN '06/13/2014' AND '07/
SELECT CASE
WHEN CONVERT(VARCHAR,CAST('6/14/2016' AS DATETIME),101) BETWEEN '06/13/2014' AND '07/04/2014'
THEN 'Yes'
ELSE 'NO'
END
有人能给我解释一下它是如何计算为真的吗?你的问题是你在比较不同的数据类型。如果你只是比较日期,你就不会有问题
SELECT CASE
WHEN CAST('6/14/2016' AS DATETIME) BETWEEN '06/13/2014'
AND '07/04/2014'
THEN 'Yes'
ELSE 'NO'
END
在我看来,你基本上是把它们当作文本(varchar)来处理,它会一个字符一个字符地处理
etc etc当日期转换为
VARCHAR
时,您正在比较字符串。
我打赌字符串是按字母顺序排列的。让我们检验一下这个理论:
declare @t table (a varchar(10))
insert into @t select '06/14/2016'
insert into @t select '06/13/2014'
insert into @t select '07/04/2014'
select a from @t order by a
这将输出:
a
----------
06/13/2014
06/14/2016
07/04/2014
(3 row(s) affected)
您2016年的日期是第二个记录,因此它将落在其他日期之间。如果要将这些视为日期,请不要转换为VARCHAR
。然后,其他两个日期将隐式转换为日期类型:
SELECT CASE WHEN CAST('6/14/2016' AS DATETIME) BETWEEN '06/13/2014' AND '07/04/2014' THEN 'Yes' ELSE 'NO' END
将不会输出您期望的结果
PS:为了避免不可预测的结果,请始终声明/转换为
VARCHAR(n)
,因为VARCHAR
转换在不指定大小的情况下使用它遇到的第一个字符串来确定结果集中列的大小,其余的可能会被截断。convert(cast(..)的最终结果属于varchar
类型。之间的中的常量也是字符串。因此,Sql server别无选择,只能应用字符串比较。它正在进行字符串比较,而不是日期比较。当值实际上是日期时,这是危险的。它比较每个ascii字符的值。您可以使用这样的表()来查看ascii字符的值。
2016年6月13日
2016年6月14日
2014年4月7日
一次可容纳1列。0是相同的。7大于6。因此,2014年4月7日是您的最大价值。在达到3/4值之前,前两个日期是相同的。3比4小。因此,2016年6月13日少于2016年6月14日
由于具有较高或较低值的第一个字符决定字符串是否大于或小于,因此除非将所有日期格式化为yyyy-mm-dd格式,否则它不适用于日期。但是,最好将日期作为日期而不是字符串进行比较Simple。。。将日期转换为字符串时,字符串不能介于日期之间。;)回答得好!它解释了为什么会介于两者之间,并指出了数据类型问题以及如何修复预期行为。感谢您的解释:)这很有意义。当我比较日期时,我将它们作为日期进行比较。我列出的代码是在几年前编写的一个程序中(不是我写的),它说“你在比较”我不一定是指作为一个人的你,而是作为代码的你:)处理旧代码可能很困难,我很清楚。谢谢你的解释:)这很有意义,直到你看到最后一个字符。6不在4和4之间。我认为@ajeh比我解释得更好,它是按字母顺序排序的,而不是按日期排序的。