Sql server 是否在联接中使用subselect更新表?

Sql server 是否在联接中使用subselect更新表?,sql-server,tsql,Sql Server,Tsql,我正在尝试使用subselect更新具有列别名的表。问题是,当我添加内部联接时,脚本会中断: 此更新有效,但与子选择没有内部联接: declare @erase table ( id varchar(10), total int ) insert into @erase (id) select 'x' declare @var1 int = 10 declare @var2 int = 10 declare @var3 int = 10 declare @var10 int = 10 decl

我正在尝试使用subselect更新具有列别名的表。问题是,当我添加内部联接时,脚本会中断:

此更新有效,但与子选择没有内部联接:

declare @erase table
(
id varchar(10),
total int
)
insert into @erase (id) select 'x'

declare @var1 int = 10
declare @var2 int = 10
declare @var3 int = 10
declare @var10 int = 10
declare @var11 int = 10
declare @var12 int = 10

update @erase 
set id = num / den
FROM
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as 'num',
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as 'den'
) as innerTable
但当我添加一个
连接时,它会断开:

declare @erase table
(
id varchar(10),
total int
)
insert into @erase (id) select 'x'

declare @var1 int = 10
declare @var2 int = 10
declare @var3 int = 10
declare @var10 int = 10
declare @var11 int = 10
declare @var12 int = 10

update @erase 
set id = innerTable.num / innertable.den
from @erase inner join innertable on
@erase.id = innertable.id
FROM
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as 'num',
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as 'den'
) as innerTable
我想使用
cte
,但我需要为
num/den
添加一个存储库。以下操作将不起作用:

;with cte as
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as 'num',
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as 'den',
    num / den as 'total' -- will break
)
update @erase 
set total = cte.total
from @erase inner join cte on
@erase.id = cte.id
如何在生成
num/den
的同一事务中更新
@erase

编辑: 我找到了解决方法,但仍无法使用最终值“total”进行更新:

;with cte as
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as 'num',
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as 'den',
    num / den as 'total' -- will break
)
update @erase 
set total = num / den --Although I prefer using alias total.
from @erase inner join cte on
@erase.id = cte.id
首先,这个样本:

update @erase 
set id = innerTable.num / innertable.den
from @erase inner join innertable on
@erase.id = innertable.id
FROM
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as 'num',
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as 'den'
) as innerTable
这里的问题是有两个FROM子句。您可以通过指定
innertable
inline来修复它,如下所示:

update @erase 
set id = innerTable.num / innertable.den
from @erase 
inner join (
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as num,
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as den
) innertable on @erase.id = innertable.id
然后是CTE版本:

with cte as
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as 'num',
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as 'den',
    num / den as 'total' -- will break
)
这里的问题是
total
行上的
num
den
尚未作为可用名称存在。您可以通过多种方式解决此问题,但有一种方法是将查询分层到多个CTE中:

with cte1 as
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as num,
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as den,
), 
cte2 As (
    select *,  num/den as total from cte1
)
update @erase 
set total = cte2.total
from @erase 
inner join cte2 on @erase.id = cte2.id
另一个选项是重复表达式:

with cte as
(
    select 
    'x' as id,
    @var1 * @var2 * @var3 * @var10* @var11* @var12 as num,
    @var1 + @var2 + @var3 + @var10+ @var11+ @var12 as den,
    ( @var1 * @var2 * @var3 * @var10* @var11* @var12 )
      / 
    ( @var1 + @var2 + @var3 + @var10+ @var11+ @var12 ) as total
)
update @erase 
set total = cte.total
from @erase 
inner join cte on @erase.id = cte.id

非常感谢你。