【问题标题】:Assign data in a SELECT>CASE statement, then use in WHERE clause?在 SELECT>CASE 语句中分配数据,然后在 WHERE 子句中使用?
【发布时间】:2016-04-26 11:05:48
【问题描述】:

我有一个查询,我在 SELECT 中使用 CASE 语句来分配“团队”列的值。然后我希望能够使用我在 WHERE 子句中分配的值。有关示例,请参阅下面的示例查询。

在我的简化示例中,我知道我可以在 WHERE 子句中使用 s.id 值并获得所需的结果,但是我正在处理一个更复杂的场景,其中实际使用字符串会有所帮助我在 WHERE 子句中赋值。

这可能吗?我正在使用 MS SQL Server 2012。

在我进行的搜索中,无论哪种方式,我都没有找到任何确定的信息。提前致谢!

SELECT s.tickedNum, s.ticketSummary,'Team' =
      CASE
         WHEN s.id in (100) THEN 'Team A'
         WHEN s.id in (200) THEN 'Team B'
         WHEN s.id in (300) THEN 'Team C'
         ELSE 'Unknown'
      END,
FROM supportTable s
WHERE
'Team' = 'Team B'

【问题讨论】:

  • 不能这样做。您需要一个子查询或 CTE。您不能在其对应的where 子句中使用在select 中定义的别名。
  • 如果你真的想也可以使用交叉申请

标签: sql sql-server


【解决方案1】:

Yoiu 不能在 WHERE 子句中引用别名,因为 WHERE 计算通常在列表达式之前评估以确定如何收集正确的行。

您可以在 WHERE 子句中重复 CASE 或使用子查询:

SELECT * FROM
(
SELECT s.tickedNum, s.ticketSummary,
      CASE
         WHEN s.id in (100) THEN 'Team A'
         WHEN s.id in (200) THEN 'Team B'
         WHEN s.id in (300) THEN 'Team C'
         ELSE 'Unknown'
      END AS Team,
FROM supportTable s
) inner
WHERE
inner.Team = 'Team B'

由于你的 where 子句只匹配一个可能的 CASE,你也可以这样做

SELECT s.tickedNum, s.ticketSummary,
      CASE
         WHEN s.id in (100) THEN 'Team A'
         WHEN s.id in (200) THEN 'Team B'
         WHEN s.id in (300) THEN 'Team C'
         ELSE 'Unknown'
      END AS Team,
FROM supportTable s
WHERE s.id = 200  /* equivalent to 'Team B' */

【讨论】:

  • 不是“通常在...之前评估”,而是“总是在...之前评估”。
  • @PieterGeerkens 当涉及到特定于实现的 SQL 答案时,我尽量避免绝对化,因为有很多变化,完全有可能某些 frings 平台以不同的顺序评估查询。但你是对的。在大多数(如果不是全部)平台中,首先评估 where 子句。
  • 在 SQL 中,必须首先评估 WHERE - 与 LINQ 中 Select() 遵循 Where() 的原因完全相同:语言的数学基础需要它。但是,我确实同意您对绝对谨慎的观点。
【解决方案2】:

在其上一个阶段完成的任何操作对其下一个逻辑阶段都是可见的。所以顺序就像 from ,where,group by ,have,select ,order by ,top..你可以看到来自 Itzik Ben Gan here

的权威列表

在你的情况下,teamA,TeamB 的分配是在 where 子句完成之后完成的。所以 where 不知道它们..

如果你想这样做,你需要在 CTE 或一些派生表中引用它们,否则你可以使用交叉应用..

仅用于演示。在这种情况下不需要这样做,即使执行计划更简单,具有哈希匹配(如果您在 ID 上有索引,将用于合并连接)和计算标量

create table test
(
id int,
name varchar(3)
)


insert into test
select 1,'abc'
union all
select 2,'cde'

select id,case id when 1 then 'abc'
                   when 2 then 'cde'
                   else null end  'values'
from test t1
cross apply
(select case id when 1 then 'abc'
                   when 2 then 'cde'
                   else null end  'values_apply' from test t2 where t1.id=t2.id) a
where a.values_apply='abc'

输出:

id value
1   abc

【讨论】:

    猜你喜欢
    • 2021-03-14
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2013-03-23
    • 2013-10-16
    • 2017-01-27
    相关资源
    最近更新 更多