SQL Server 2008 - 从CASE WHEN语句返回非空值

时间:2013-09-25 19:31:37

标签: sql-server-2008 null case

SELECT *,
    CASE 
    when PERSONNUM in ('x','y','z')
    then 'Home'
    end as HomeEmployees
    when PERSONNUM in ('a','b','c')
    then 'Away'
    end as AwayEmployees
FROM dbo.ALLTOTALS
where PERSONNUM in ('a','b','c','x','y','z')
    and HomeEmployees is not null

- 基于选择PERSONNUM字段的多个小时

3 个答案:

答案 0 :(得分:2)

为什么不从

修改WHERE子句
where HomeEmployees is not null

进入

WHERE PERSONNUM IN ('x', 'y', 'z')

因此,仅选择列x , y, z中值为PERSONNUM的记录。

答案 1 :(得分:0)

您还可以将案例投影到别名中,然后使用外部查询对其进行过滤,如下所示:

SELECT * -- Or better still, explicitly identify each needed column
FROM
(
  SELECT *, -- Or better still, explicitly identify each needed column
    CASE 
        WHEN PERSONNUM in ('x','y','z')
        THEN 'Home'
        END AS HomeEmployees
    FROM AllTotals
) AS FilteredEmployees 
WHERE 
  FilteredEmployees.HomeEmployees IS NOT NULL;

或作为CTE:

WITH FilteredEmployees AS
(
  SELECT *, 
    CASE 
        WHEN PERSONNUM in ('x','y','z')
        THEN 'Home'
        END AS HomeEmployees
    FROM AllTotals
)
SELECT *
  FROM FilteredEmployees
  WHERE FilteredEmployees.HomeEmployees IS NOT NULL;

答案 2 :(得分:0)

Logical order of execution(请参阅“SELECT语句的逻辑处理顺序”一节)以下SELECT语句:

DECLARE @MyTable TABLE
(
    ID      INT IDENTITY PRIMARY KEY,
    [Date]  SMALLDATETIME NOT NULL,
    WorkingTime INT NOT NULL,
    EmployeeID  INT NULL
);
INSERT  @MyTable ([Date], WorkingTime, EmployeeID)
SELECT  '20130801', 1, 123 UNION ALL 
SELECT  '20130802', 0, 124 UNION ALL 
SELECT  '20130803', 0, 125; 

SELECT  x.ID,
        CASE WHEN x.ID % 2 = 1 THEN x.ID END AS EmployeeID
FROM    @MyTable x
WHERE   EmployeeID IS NOT NULL;

  1. FROM @myTable x
  2. WHERE EmployeeID不为NULL(< => WHERE x.EmployeeID IS NOT NULL)
  3. SELECT x.ID,CASE ... END AS EmployeeID
  4. 如您所见,CASE ... END AS EmployeeID表达式被评估为 AFTER WHERE子句。这也意味着EmployeeID IS NOT NULL谓词引用了x.EmployeeID列,而不是来自EmployeeID子句的SELECT别名。

    这就是我得到以下结果的原因:

    ID          EmployeeID
    ----------- -----------
    1           1
    2           NULL
    3           3
    

    如果您想按EmployeeID别名进行过滤,则可以使用以下解决方案之一:

    SELECT  x.ID,
            CASE WHEN x.ID % 2 = 1 THEN x.ID END AS EmployeeID
    FROM    @MyTable x
    WHERE   CASE WHEN x.ID % 2 = 1 THEN x.ID END IS NOT NULL;
    
    SELECT *
    FROM
    (
    SELECT  x.ID,
            CASE WHEN x.ID % 2 = 1 THEN x.ID END AS EmployeeID
    FROM    @MyTable x
    ) src
    WHERE   src.EmployeeID IS NOT NULL;
    

    注意:使用与列名同名的别名不是一个好主意。这造成了混乱。