Sql CASE语句别名的WHERE子句

Sql CASE语句别名的WHERE子句,sql,sql-server,tsql,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

我这里有一个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

WHERE子句对SELECT列表中的别名一无所知

原因:MS SQL server中有一个逻辑处理顺序,其中在选择列表之前计算

因此,一种方法是创建一个内部查询并将其放在外部

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
另一种方法是在where子句中放入case,如

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

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

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())

这是MySQL还是sql server?如果是后者,则除了同一表达式中的ORDER BY之外,不能在任何位置引用列上的别名。您需要重复该表达式,或者在FROM中使用CTE或子查询。我不知道MySQL是否也是如此,但如果相同或相似,我也不会感到惊讶。这是一个大小写表达式,not语句可以删除。ma.CancelDate不是NULL,因为ma.CancelDate SQL Server!“对不起,”马特拉森漏了一个括号。添加回来。我希望优化器能够将IS NOT NULL吸收到