带有WHERE子句的SQL查询CASE语句

问题描述 投票:2回答:3

我已经构建了以下使用多条件CASE语句的查询。这是具有多条件CASE语句的正确/最佳方式吗?

它的工作时间很长,因为我没有在where中引用CASE语句。我得到“无效的列名称'方案'。”

如何在查询的WHERE部分中引用Scenario?

select 
    TPID
    ,(CASE WHEN 
        ([AOppty] > 0) and ([Entitlements] = 0) and ([B Agreement] = 0 and [C Agreement] = 0)
    THEN 1 ELSE 0 END) as ScenarioA
from RulesEngine R
--where ScenarioA = 1
sql sql-server
3个回答
3
投票

SQL Server允许您为此使用公用表表达式:

WITH
    Rules (TPID, ScenarioA)
AS (
    SELECT 
        TPID
    ,   (CASE WHEN 
            ([AOppty] > 0) AND ([Entitlements] = 0) AND ([B Agreement] = 0 and [C Agreement] = 0)
            THEN 1 ELSE 0 END
        ) AS ScenarioA
)
SELECT
    TPID, ScenarioA
WHERE
    ScenarioA = ...

1
投票

你不能。您可以使用子查询和where子句:

 select r.*
 from (select TPID,
              (CASE WHEN [M365 E3 Oppty] > 0) and ([EMS Entitlements] = 0) and ([EMS E3 Agreement] = 0 and [EMS E5 Agreement] = 0
                    THEN 1 ELSE 0
               END) as ScenarioA
       from RulesEngine R
      ) R
 where ScenarioA . . .

当然,对于这种简单的情况,它更简单:

select TPID, 1 as ScenarioA
from RulesEngine R
where [M365 E3 Oppty] > 0) and ([EMS Entitlements] = 0) and ([EMS E3 Agreement] = 0 and [EMS E5 Agreement] = 0;

CASE并没有增加多少。

对于更复杂的表达式,SQL Server也有cross apply

select r.tpid, v.ScenarioA
from RulesEngine r cross apply
     (values ( CASE WHEN [M365 E3 Oppty] > 0) and ([EMS Entitlements] = 0) and ([EMS E3 Agreement] = 0 and [EMS E5 Agreement] = 0
                    THEN 1 ELSE 0
               END
             )
      ) v(ScenarioA)
 where v.ScenarioA . . .;

在我看来,cross apply是最干净的解决方案,因为它可以轻松添加多个相互依赖的表达式,而无需使用子查询和多个CTE。


0
投票

将其用作子查询。

select * from 
(
select 
    TPID
    ,(CASE WHEN 
        ([M365 E3 Oppty] > 0) and ([EMS Entitlements] = 0) and ([EMS E3 Agreement] = 0 and [EMS E5 Agreement] = 0)
    THEN 1 ELSE 0 END) as ScenarioA
from RulesEngine
) R where ScenarioA = 1

理想情况下,这应该适用于大多数RDBMS。

© www.soinside.com 2019 - 2024. All rights reserved.