6

我想做这样的事情

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

4

3 回答 3

13

如果可能的话,想办法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 ALLcte,而不是使用if- 毕竟,被组合的两个查询无论如何都必须具有兼容的结果集,才能使您的原始问题有意义。

于 2012-06-25T07:16:54.133 回答
6

您不能这样做 - 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)

于 2012-06-25T06:49:02.277 回答
4

with cte (...) select from cte ...一个单一的声明。不是“跟随”语句,而是语句一部分。您要求将声明一分为二,这显然是不可能的。

作为一般规则,SQL 是一种非常不友好的语言,用于 DRY 和避免代码重复。尝试使代码更易于维护、更易读,或者只是尝试保存一些击键可能(并且通常会)导致严重的运行时性能损失(例如,尝试将 CTE 移动到表值函数 UDF 中)。最简单的事情就是咬紧牙关(这次和将来......)并写两次 CTE。有时将 CTE 实体化为 #temp 表然后对 #temp 表进行操作是有意义的,但仅在某些时候

这种现状是不幸的,但是您可以从委员会的设计中获得一切...

于 2012-06-25T08:50:08.413 回答