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

时间:2017-12-24 19:30:20

标签: sql sql-server

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

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

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

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

3 个答案:

答案 0 :(得分: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 :(得分: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。

答案 2 :(得分: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。