问题描述
我在从前同事那里继承的查询中发现了一个错误,我正在尝试修复它,但这是一个我以前从未遇到过的奇怪问题..这是原始查询的片段:
CAST(CONCAT(DATEPART(YYYY,getdate()),(CASE
WHEN DATEPART(WW,getdate()) < 10
THEN CONCAT('0',DATEPART(WW,getdate()))
ELSE DATEPART(WW,getdate())
END)
) AS INT)
当 getdate() = 2021-01-08 10:16:41.440 查询结果
20212
预期结果应该是
202102
我发现问题依赖于 CASE 语句。当我尝试将 THEN 子句更改为
CAST(CONCAT(DATEPART(YYYY,getdate()) < 10
THEN RIGHT('0'+ CONVERT(VARCHAR(2),getdate())),2)
ELSE DATEPART(WW,getdate())
END)
) AS INT)
我还是明白了
20212
但是当我跑步时
SELECT RIGHT('0'+ CONVERT(VARCHAR(2),2)
我明白
02
有人能解释一下吗?为什么它可以在 CASE 语句之外运行,而不能在内部运行?
解决方法
case
表达式返回单个值并且具有单个类型。如果任何返回值是数字,则返回值是数字,而不是字符串。
要获取字符串,请使用 datename()
:
(CASE WHEN DATEPART(WW,getdate()) < 10
THEN CONCAT('0',DATENAME(WW,getdate()))
ELSE DATENAME(WW,getdate())
END)
或者你可以简化你的逻辑:
RIGHT(CONCAT('0',getdate()),2)
或者简化一切。例如,一个数字可能就足够了:
YEAR(GETDATE()) * 100 + DATEPART(WW,getdate())
,
您的查询已隐式转换为 INT
:
CAST(CONCAT(DATEPART(YYYY,(CASE
WHEN DATEPART(WW,getdate()) < 10
THEN RIGHT('0'+ CONVERT(VARCHAR(2),DATEPART(WW,getdate())),2)
ELSE CAST(DATEPART(WW,getdate()) AS VARCHAR(2)) -- adding explicit cast here
END)
) AS INT)
,
我可以用简单的方法提供建议:
SELECT
CAST(
CONCAT(
DATEPART(YYYY,RIGHT(CONCAT('0000',2)
) AS INT);