仅执行ELSE语句时的情况



我以前从未见过这种情况,但当我在SQL Server中SELECT一个CASE WHEN语句时,它会执行ELSE语句。这怎么可能?是因为它不能在同一列中处理不同类型的值类型吗?

SELECT CASE WHEN len(birthDate)=4 THEN birthDate
WHEN birthDate = '' THEN ''
ELSE CONVERT(datetime, birthDate)
END AS [birthDateConverted]
,[birthDate]
FROM BirthDayTable

结果如下:

birthDateConverted          birthDate
1951-01-01 00:00:00.000     1951
1936-06-19 00:00:00.000     June 19, 1936
1948-03-11 00:00:00.000     March 11, 1948
NULL                        

我想要以下产品:

birthDateConverted          birthDate
1951                        1951
1936-06-19                  June 19, 1936
1948-03-11                  March 11, 1948
NULL    

我也不明白为什么当我指定"时会得到NULL。但这一部分不如第一部分重要,因为我只希望有一年,而只有一年是指定的。

先试试这个,然后在查询中相应地实现逻辑。将@birthDate变量替换为所需的输入字符串。

还有一个检查可以使用ISDATE((函数执行,该函数检查输入的字符串是否为有效日期,如果需要,可以相应地更改逻辑。

关于isdate((函数的更多信息可以在这里找到

DECLARE @birthDate varchar(20)=''
SET @birthDate='March 11, 1948'
SELECT CASE WHEN len(@birthDate)=4 THEN CONVERT(varchar, @birthDate)
WHEN CONVERT(varchar,@birthDate) = '' THEN ''
ELSE CONVERT(varchar,CONVERT(date, @birthDate))
END AS [birthDateConverted]

NULL不等于'',因此,您可以执行以下操作:

SELECT (CASE WHEN len(birthDate) = 4 
THEN birthDate
WHEN birthDate IS NULL 
THEN ''
ELSE CONVERT(datetime, birthDate)
END) AS [birthDateConverted],
[birthDate]
FROM BirthDayTable;

但是,''将隐式转换为日期时间。

您试图在一列中存储多个类型,这在SQL中是不可能的。因此,当查询在SQL Server上执行时,它将在第一个读取类型中键入所有值。在您的情况下,由于将null值与空字符串进行比较,第二个条件总是失败,在SQL中,您可以通过ISNULL(birthDate,"(="来实现这一点,因此当值为null或为空时,它总是返回true。因此,您不能设置一个空字符串或DateTime值的日期字符串,您的要求是无效的。我想你正在寻找这个,它将把DateTime值格式化为字符串

SELECT (CASE WHEN ISDATE(birthDate) = 1 
THEN CONVERT(varchar, CONVERT(datetime,birthDate), 110)
ELSE birthDate
END) AS [birthDateConverted], [birthDate]
FROM    BirthDayTable;

我尝试了以下方法,适用于我的案例。希望其他人也能从中受益

SELECT CASE WHEN len(birthDate)>4 
THEN CONCAT(YEAR(birthDate), '-', RIGHT('00' + CONVERT(NVARCHAR(2), DATEPART(MONTH, (birthDate))),2), '-', 
RIGHT('00' + CONVERT(NVARCHAR(2), DATEPART(DAY, (birthDate))),2)) 
WHEN len(birthDate)=4 
THEN CONVERT(nvarchar(255), birthDate)
ELSE '' 
END AS [birthDateConverted]
,[birthDate]
FROM BirthDayTable;

CASE将只返回1个数据类型
在您的SQL中,由于该转换将返回DATETIME
由于"1951"随后被隐式转换为DATETIME,因此它返回"1951-01-01 00:00:00.000"。

因此,让CASE返回一个VARCHAR。

如果您使用的是MS SQL Server 2012或更高版本,则可以使用TRY_CONVERT验证varchar是否可以转换为日期或日期时间。

因为当转换尝试失败时,TRY_CONVERT将返回NULL。

示例片段:

select *, 
(case 
when birthDate like '[0-9][0-9][0-9][0-9]' then birthDate
when birthDate like '%[0-9]%' and try_convert(date, birthDate) is not null 
then convert(varchar(10), convert(date, birthDate), 20)
else ''
end) as birthDateConverted
from (values 
(1,'1951'),
(2,'June 19, 1936'),
(3,'March 11, 1948'),
(4,''),
(5,null),
(6,'ABCD')
) t(id, birthDate);

退货:

id  birthDate      birthDateConverted
--  -------------- ------------------
1   1951           1951
2   June 19, 1936  1936-06-19
3   March 11, 1948 1948-03-11
4       
5   NULL    
6   ABCD    

最新更新