CASE语句别名的WHERE子句

时间:2018-06-18 12:48:11

标签: sql sql-server tsql

我在这里有一个CASE表达式,它添加了一个带有布尔值的新列IsAccountActive。然后我如何添加where子句以仅查询活动的行?

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

2 个答案:

答案 0 :(得分:2)

WHERE子句对SELECT列表中的别名没有任何想法。

原因: MS SQL服务器( see link here )中存在逻辑处理顺序,其中WHERE在SELECT列表之前计算

所以一种方法是创建一个内部查询并放在外面。

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

另一种方法是将case放在where子句中,如

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

答案 1 :(得分:2)

将您的查询包装在派生表(子查询)中,然后您可以对其结果应用该条件:

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

请注意

(sa.CancelDate IS NOT NULL AND sa.CancelDate <= GETDATE())

可以简化为

(sa.CancelDate <= GETDATE())