我构建了以下使用多条件 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
答案 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。