为什么列名没有使用Case for date捕获MS SQL中的占位符?

问题描述 投票:0回答:3

我试图让占位符在他们受尊敬的列中,但只获得NULL。帮助我摆脱错误的地方。

select [Created Date],
Case 
when [Created Date] BETWEEN '16/07/2016' AND '15/07/2017' then '2073/74' 
when [Created Date] BETWEEN '16/07/2017' AND '15/07/2018' then '2073/74' 
when [Created Date] BETWEEN '16/07/2018' AND '15/07/2019' then '2074/75' 
end as Fiscal_Year ,
[Vendor Name]
from dbo.Vendor 

结果:

Created Date        Fiscal_Year Vendor Name
30/11/2017 08:12 PM   NULL      Al Safa Food Trading
30/11/2017 08:13 PM   NULL      Star Fresh Foods FZC
30/11/2017 08:43 PM   NULL      Green Foods Import - Export
30/11/2017 08:47 PM   NULL      SIDCO Foods Trading
30/11/2017 08:48 PM   NULL      Gulf Foods Trading
30/11/2017 08:54 PM   NULL      Lebanon Crescent Foods Impex
sql sql-server
3个回答
1
投票

发表回答,作为评论并不足以解释这一点。

从评论中可以清楚地看出OP正在使用varchar(或类似的)来存储日期和时间。这是非常糟糕的做法。为什么这是一个问题有很多含义。

举个例子,让我们使用OP在这里尝试做的事情:

Case when [Created Date] BETWEEN '16/07/2017' AND '15/07/2018' then '2073/74' END

在这里,[Created Date]varchar值为'30/11/2017 08:12 PM'。现在,我们都知道2017年11月30日的日期是2017年7月16日到2018年7月15日,但是,varchar?答案是不。该字符串以字符3开头。 CASE中两个“日期”的最高起始特征是1. 3大于1,因此'30/11/2017 08:12 PM'不在'16 / 07/2017'和'15/07/2018'之间。

现在,还有其他含义。假设我们在[Created Date]上有一个索引,我们想对2017年3月的日期进行“简单查询”。我们认为答案是:

SELECT *
FROM MyTable
WHERE [Created Date] >= '20170301'
  AND [Created Date] < '20170401';

这不会返回我们期望的结果(我实际上期望它不返回),因为'20170301'将被视为字符串,而不是日期。那么,为什么不使用convert

SELECT *
FROM MyTable
WHERE CONVERT(datetime2(0),[Created Date]) >= '20170301'
  AND CONVERT(datetime2(0),[Created Date]) < '20170401';

好吧,那会奏效,但INDEX现在完全没用了。 date的排序与varchar完全不同。索引通过对该索引中的数据进行排序来工作,以便可以轻松找到数据。

采用以下值并“排序”它们:

29/11/2016 08:13 AM
30/10/2017 08:13 PM
19/12/2018 08:13 AM

你得到了什么答案?好吧,如果你把它们分类为日期,那么你得到:

29/11/2016 08:13 AM
30/10/2017 08:13 PM
19/12/2018 08:13 AM

但是,OP不存储日期,它们存储的是varchar。因此,正确答案是:

19/12/2018 08:13 AM
29/11/2017 08:13 AM
30/10/2016 08:13 PM

这是“正确”,2018年12月19日是2017年和2016年之前的日期?并且,2017年11月29日再次在2016年10月30日之前。

你看到这个问题吗?不要将数据存储为WRONG数据类型。永远。将日期存储为日期,数字,数字,字符串作为字符串。没有理由不这样做。


2
投票

试试这个

select [Created Date],
Case 
when cast([Created Date] as Date) BETWEEN cast('16/07/2016' as date) AND '15/07/2017' then '2073/74' 
when cast([Created Date] as Date) BETWEEN cast('16/07/2017'as date) AND '15/07/2018' then '2073/74' 
when cast([Created Date] as Date) BETWEEN cast('16/07/2018'as date) AND '15/07/2019' then '2074/75' 
end as Fiscal_Year ,
[Vendor Name]
from dbo.Vendor 

0
投票

试试这个

select [Created Date],
Case 
when [Created Date] BETWEEN '2016-07-16' AND '2017-07-15' then '2073/74' 
when [Created Date] BETWEEN '2017-07-16' AND '2018-07-15' then '2073/74' 
when [Created Date] BETWEEN '2018-07-16' AND '2019-07-15' then '2074/75' 
end as Fiscal_Year ,
[Vendor Name]
from dbo.Vendor 
© www.soinside.com 2019 - 2024. All rights reserved.