SQL Server:CASE不起作用

时间:2011-12-01 06:50:15

标签: sql sql-server-2005

SELECT 
   a.componentId, a.uniqueCode, 
   'sd'= CASE 
            WHEN RTRIM(LTRIM(b.name)) IS NULL OR RTRIM(LTRIM(b.uniqueCode)) IS NULL 
               THEN isnull(b.uniqueCode,'')+isnull(b.name,'') 
            WHEN RTRIM(LTRIM(b.name)) IS NULL AND RTRIM(LTRIM(b.uniqueCode)) IS NULL
               THEN isnull(b.uniqueCode,'')+isnull(b.name,'')
            ELSE b.uniqueCode + '(' + (b.name) + ')'
    END, 
    a.specialization 
FROM Doctors a 
LEFT OUTER JOIN Territories b ON a.locationId = b.componentId;

假设b.uniqueCode = T003b.name = Dhanmondi 01,则sd应为T003(Dhanmondi 01)

现在,如果b.name = NULL则sd应为T003,但我的查询结果显示为T003()

我的T-SQL查询有什么问题?

3 个答案:

答案 0 :(得分:3)

您确定b.name是null吗?如果它有一个空字符串而不是null,那么你会看到结果。顺便说一句,使用rtrim/ltrim进行检查时,is null内容完全不必要,而您的第二个when将永远不会发生,因为如果任一列{{{}},您将始终在第一个when中结束{1}}。

这会将空字符串视为null:

null

答案 1 :(得分:2)

让我们先解决一些基础知识......

您的第二个WHEN无法覆盖,因为较早的WHEN在第二个true之前始终为WHEN(无效)(均为空)。

如果参数为RTRIM()

LTRIM()NULL将仅返回NULL,因此这两个条件表达式是相同的:

  • RTRIM(LTRIM(b.name)) IS NULL
  • b.name IS NULL

删除冗余代码(包括无法访问的WHEN),可以让您大大简化代码:

CASE
    WHEN b.name IS NULL OR b.uniqueCode IS NULL 
        THEN isnull(b.uniqueCode,'') + isnull(b.name,'')
    ELSE b.uniqueCode + '(' + b.name + ')'
END

现在我们可以阅读了......

最可能的解释是b.name 空白,而不是NULL

答案 2 :(得分:1)

在SQL和所有流行的SQL产品中 - 除了Oracle - NULL和空字符串''是两回事。所以,你应该检查两个选项:

SELECT a.componentId, a.uniqueCode, 
    CASE 
        WHEN b.name IS NULL OR b.name = ''
            THEN COALESCE(b.uniqueCode, '')
        WHEN b.uniqueCode IS NULL OR b.uniqueCode = ''
            THEN b.name
            ELSE b.uniqueCode + '(' + b.name + ')'
    END AS sd
     , a.specialization 
...

或删除前导和尾随空格:

    CASE 
        WHEN b.name IS NULL OR RTRIM(LTRIM(b.name)) = ''
            THEN COALESCE(RTRIM(LTRIM(b.uniqueCode)), '')
        WHEN b.uniqueCode IS NULL OR RTRIM(LTRIM(b.uniqueCode)) = ''
            THEN RTRIM(LTRIM(b.name))
            ELSE RTRIM(LTRIM(b.uniqueCode)) + '(' 
               + RTRIM(LTRIM(b.name)) + ')'
    END AS sd