CONCAT 在 case 语句中前导 0

CONCAT leading 0 in case statement

我在从以前的同事那里继承的查询中发现了一个错误,我正在尝试修复它,但这是一个我以前从未遇到过的奇怪问题。这是原始查询的片段:

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()), 
  (CASE 
    WHEN DATEPART(WW,getdate()) < 10 
    THEN RIGHT('0'+ CONVERT(VARCHAR(2), DATEPART(WW,getdate())),2) 
    ELSE DATEPART(WW,getdate()) 
   END)
) AS INT)

我还是得到

20212

但是当我运行

SELECT RIGHT('0'+ CONVERT(VARCHAR(2), DATEPART(WW,getdate())),2)

我明白了

02

谁能解释一下?为什么它在 CASE 语句之外起作用,但在 CASE 语句内不起作用?

case 表达式 return 单个值并且具有单个类型。如果任何 return 值是数字,则 return 值是数字,而不是字符串。

要获取字符串,请使用 datename():

(CASE WHEN DATEPART(WW, getdate()) < 10 
      THEN CONCAT('0', DATENAME(WW,getdate())) 
      ELSE DATENAME(WW, getdate()) 
 END)

或者您可以简化您的逻辑:

RIGHT(CONCAT('0', DATENAME(WW, getdate()), 2)

或者简化一切。例如,一个数字可能就足够了:

YEAR(GETDATE()) * 100 + DATEPART(WW, getdate())

您的查询已隐式转换为 INT:

CAST(CONCAT(DATEPART(YYYY,getdate()), 
  (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,getdate()), 
     RIGHT(CONCAT('0000', DATEPART(WW,getdate())), 2)
) AS INT);

你可以try T-SQL here