I have a CASE expression here that is adding a new column IsAccountActive
with boolean values. How can I then add a where clause to only query for the rows that are active?
SELECT
ma.CustomerID,
ma.FirstName,
ma.LastName,
(
CASE WHEN (
sa.Active < 1
OR
ma.Active < 1
OR
(sa.CancelDate IS NOT NULL AND sa.CancelDate <= GETDATE())
OR
(ma.CancelDate IS NOT NULL AND ma.CancelDate <= GETDATE())
OR
(sa.ExpireDate IS NOT NULL AND DATEADD(dd, sa.Extension + 1, sa.ExpireDate) <= GETDATE())
) THEN
0
ELSE
1
END
) as IsAccountActive
FROM MasterAccounts ma
INNER JOIN SubAccounts sa
ON sa.CustomerID = ma.CustomerID
INNER JOIN MasterAccountData mad
ON mad.CustomerID = sa.CustomerID
WHERE mad.AccountDataTypeID = 20001
AND mad.Data = ''
AND IsAccountActive = 1
WHERE clause does not have any idea about aliased in SELECT list.
Reason: There's a logical processing order in MS SQL server ( see link here ) and in it WHERE is computed before the SELECT list
So one way is to create an inner query and put where outside.
Select * from
(
SELECT
ma.CustomerID,
ma.FirstName,
ma.LastName,
(
CASE WHEN (
sa.Active < 1
OR
ma.Active < 1
OR
(sa.CancelDate IS NOT NULL AND sa.CancelDate <= GETDATE())
OR
(ma.CancelDate IS NOT NULL AND ma.CancelDate <= GETDATE())
OR
(sa.ExpireDate IS NOT NULL AND DATEADD(dd, sa.Extension + 1, sa.ExpireDate) <= GETDATE())
) THEN
0
ELSE
1
END
) as IsAccountActive
FROM MasterAccounts ma
INNER JOIN SubAccounts sa
ON sa.CustomerID = ma.CustomerID
INNER JOIN MasterAccountData mad
ON mad.CustomerID = sa.CustomerID
WHERE mad.AccountDataTypeID = 20001
AND mad.Data = '')T
where T.IsAccountActive = 1
Another way is to put case in where clause like
SELECT
ma.CustomerID,
ma.FirstName,
ma.LastName
FROM MasterAccounts ma
INNER JOIN SubAccounts sa
ON sa.CustomerID = ma.CustomerID
INNER JOIN MasterAccountData mad
ON mad.CustomerID = sa.CustomerID
WHERE mad.AccountDataTypeID = 20001
AND mad.Data = ''
AND CASE WHEN (
sa.Active < 1
OR
ma.Active < 1
OR
(sa.CancelDate IS NOT NULL AND sa.CancelDate <= GETDATE())
OR
(ma.CancelDate IS NOT NULL AND ma.CancelDate <= GETDATE())
OR
(sa.ExpireDate IS NOT NULL AND DATEADD(dd, sa.Extension + 1, sa.ExpireDate) <= GETDATE()))
THEN
0
ELSE
1
END =1
Wrap your query up in a derived table (sub-query), then you can apply that condition on its result:
SELECT *
FROM
(
SELECT
ma.CustomerID,
ma.FirstName,
ma.LastName,
(
CASE WHEN (
sa.Active < 1
OR
ma.Active < 1
OR
(sa.CancelDate IS NOT NULL AND sa.CancelDate <= GETDATE())
OR
(ma.CancelDate IS NOT NULL AND ma.CancelDate <= GETDATE())
OR
(sa.ExpireDate IS NOT NULL AND DATEADD(dd, sa.Extension + 1, sa.ExpireDate) <= GETDATE())
) THEN
0
ELSE
1
END
) as IsAccountActive
FROM MasterAccounts ma
INNER JOIN SubAccounts sa
ON sa.CustomerID = ma.CustomerID
INNER JOIN MasterAccountData mad
ON mad.CustomerID = sa.CustomerID
WHERE mad.AccountDataTypeID = 20001
AND mad.Data = ''
) dt
WHERE IsAccountActive = 1
Note that
(sa.CancelDate IS NOT NULL AND sa.CancelDate <= GETDATE())
can be simplified as
(sa.CancelDate <= GETDATE())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.