我以前从未见过这种情况,但当我在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