我想做这样的事情
declare @a int=1
if (@a=1)
with cte as
(
select UserEmail from UserTable
)
else
with cte as
(
select UserID from UserTable
)
select * from cte
这只是一个例子,我的实际查询要复杂得多。所以我不想在CTE之后写两次SELECT
声明里面IF
和声明。ELSE
我想做这样的事情
declare @a int=1
if (@a=1)
with cte as
(
select UserEmail from UserTable
)
else
with cte as
(
select UserID from UserTable
)
select * from cte
这只是一个例子,我的实际查询要复杂得多。所以我不想在CTE之后写两次SELECT
声明里面IF
和声明。ELSE
如果可能的话,想办法if
完全避免这种说法。
例如,在您的问题中这样一个微不足道的例子中:
;with CTE as (
select UserEmail from UserTable where @a = 1
union all
select UserID from UserTable where @a != 1 or @a is null
)
select /* single select statement here */
通常应该可以将一个或多个不同的查询组合成最终的UNION ALL
cte,而不是使用if
- 毕竟,被组合的两个查询无论如何都必须具有兼容的结果集,才能使您的原始问题有意义。
您不能这样做 - CTE必须紧跟一个可以引用它的 SQL 语句。您不能将 CTE 的“定义”与使用它的语句分开。
所以你需要这样做:
declare @a int=1
if (@a=1)
with cte as
(
select UserEmail from UserTable
)
select * from cte
else
with cte as
(
select UserID from UserTable
)
select * from cte
您不能拆分 CTE“定义”以供其使用 ( select * from cte
)
这with cte (...) select from cte ...
是一个单一的声明。不是“跟随”语句,而是语句的一部分。您要求将声明一分为二,这显然是不可能的。
作为一般规则,SQL 是一种非常不友好的语言,用于 DRY 和避免代码重复。尝试使代码更易于维护、更易读,或者只是尝试保存一些击键可能(并且通常会)导致严重的运行时性能损失(例如,尝试将 CTE 移动到表值函数 UDF 中)。最简单的事情就是咬紧牙关(这次和将来......)并写两次 CTE。有时将 CTE 实体化为 #temp 表然后对 #temp 表进行操作是有意义的,但仅在某些时候。