仅执行ELSE语句的情况

时间:2018-12-12 10:26:01

标签: sql-server

我之前从未见过这种情况,但是当我在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。但是这部分并不像第一部分那么重要,因为我只想指定年份,而只指定年份。

5 个答案:

答案 0 :(得分:0)

NULL不等于”,因此,您可以这样做:

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

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

答案 1 :(得分:0)

您试图将多种类型存储在一列中,这在SQL中是不可能的。因此,当查询在SQL Server上执行时,它将在第一个读取类型上键入所有值。 在您的情况下,由于将空值与空字符串进行比较,您的第二个条件始终会失败,在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;

答案 2 :(得分:0)

我尝试了以下方法,该方法适用于我的情况。希望其他人也可以从中受益

  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;

答案 3 :(得分:0)

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    

答案 4 :(得分:0)

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

您还可以使用ISDATE()函数执行另一项检查,该函数检查输入的字符串是否为有效日期,并且可以根据需要更改逻辑。

有关isdate()函数的更多信息,请参见here

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]