2017-08-24 166 views
1

包括全包容性的范畴。如果我有一个CASE表达式内容如下:使用CASE语句

CASE WHEN Category='A' THEN 'Discharged' 
    WHEN Category='B' THEN 'Not Discharged' 
    WHEN Category='A' OR Category='B' THEN 'Both' 
    END AS Status 

我注意到,CASE不显示单独的“两个”状态的记录。它只显示“已解除”或“未解除”。有没有办法让CASE表达式包含单独的'Both'结果以及每个'Discharged'或'Not Discharged'结果?

如果我在'Discharged'或'Not Discharged'之上编码'Both'的条件,输出结果会显示所有记录的'Both'。我相信这与CASE的顺序逻辑是一致的。

+0

你能否提供一些样本数据?你也可以发布整个查询吗? –

+0

你想用这个做什么,类别只能落入A和B?如果是这样的话,为什么不打印每个记录的'两个'除了放电/不放电? –

+0

此状态字段实际上被馈入BI工具以用作过滤器。 'Both'状态可以让我显示所有结果,而不必选择“已排出”和“未排出”之一。 – AS91

回答

1

CASE表达式按代码中的“外观”顺序进行评估并短路。在你的情况下,将最后的WHEN移到第一个位置。

CASE表达式使用布尔比较而不是按位。如果您的条件匹配的非这是一个好主意,有一个ELSE状况,以及避免NULL返回:

CASE 
    WHEN Category='A' AND Category='B' THEN 'Both' 
    WHEN Category='A' THEN 'Discharged' 
    WHEN Category='B' THEN 'Not Discharged' 
END AS Status 

有关按位比较试试这个:

DECLARE @Category INT = ASCII('A')|ASCII('B') 
SELECT 
    CASE 
     WHEN @Category = (ASCII('A')|ASCII('B')) THEN 'Both' 
     WHEN @Category= ASCII('A') THEN 'Discharged' 
     WHEN @Category= ASCII('B') THEN 'Not Discharged' 
    END AS Status 

注意。

参见位运算符和用途的完整列表:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/bitwise-operators-transact-sql

如果你想通过表达式过滤也就是说,它出现在WHERE子句中,那么你需要不同的看法写:

DECLARE @SearchCriteria VARCHAR(50) 
SET @SearchCriteria = 'Both' 
SELECT Category 
FROM (VALUES('A'), ('B')) AS a(Category) 
WHERE 
    Category = (CASE @SearchCriteria 
     WHEN 'Discharged' THEN 'A' 
     WHEN 'Not Discharged' THEN 'B' 
     WHEN 'Both' THEN Category 
    END) 
+0

并且不起作用,因为行级上的类别不能同时为A和B.双方的想法是它是包容性的。并不是说它可以同时出院和不出院。这是一个显示状态为'Both'的冗余行,因此当我在Both上过滤时,我基本上可以获得每个状态。 2在这种情况下。包括ELSE +1,但我没有在这里让事情变得更简单。 – AS91

+0

@ AS91 - 希望第三种选择是你需要的 – Alex

1

你可以使用UNION

SELECT person_id, 
     ... 
     CASE WHEN Category='A' THEN 'Discharged' 
      WHEN Category='B' THEN 'Not Discharged' 
     END AS Status 
    FROM table 
UNION 
SELECT person_id, 
     ... 
     'Both' AS Status 
    FROM table