Logical order of execution(see section "Logical Processing Order of the SELECT statement") for the following SELECT statement:
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;
is
- FROM @myTable x
- WHERE EmployeeID IS NOT NULL ( <=> WHERE x.EmployeeID IS NOT NULL )
- SELECT x.ID, CASE ... END AS EmployeeID
As you can see, CASE ... END AS EmployeeID expression is evaluated AFTER WHERE clause. And this means also that EmployeeID IS NOT NULL predicate references x.EmployeeID column and not the EmployeeID alias from SELECT clause.
This is the reason I get the following results:
ID EmployeeID
----------- -----------
1 1
2 NULL
3 3
If you want to filter by EmployeeID alias then you could use one of these solutions:
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;
Note: It's not a good idea to use an alias with the same name as a column name. This create confusion.