具有两列的T-SQL顺序更新
我有一个由以下人员创建的表:具有两列的T-SQL顺序更新,sql,sql-server,sql-update,window-functions,recursive-query,Sql,Sql Server,Sql Update,Window Functions,Recursive Query,我有一个由以下人员创建的表: CREATE TABLE table1 ( id INT, multiplier INT, col1 DECIMAL(10,5) ) INSERT INTO table1 VALUES (1, 2, 1.53), (2, 3, NULL), (3, 2, NULL), (4, 2, NULL), (5, 3, NULL), (6, 1, NULL) 其结果是: id multiplier col1 ---------
CREATE TABLE table1
(
id INT,
multiplier INT,
col1 DECIMAL(10,5)
)
INSERT INTO table1
VALUES (1, 2, 1.53), (2, 3, NULL), (3, 2, NULL),
(4, 2, NULL), (5, 3, NULL), (6, 1, NULL)
其结果是:
id multiplier col1
-----------------------
1 2 1.53000
2 3 NULL
3 2 NULL
4 2 NULL
5 3 NULL
6 1 NULL
我想添加一列col2
,该列被定义为multiplier*col1
,但是col1
的下一个值随后更新,以获取先前计算的col2
值
生成的表应该如下所示:
id multiplier col1 col2
---------------------------------------
1 2 1.53000 3.06000
2 3 3.06000 9.18000
3 2 9.18000 18.36000
4 2 18.36000 36.72000
5 3 36.72000 110.16000
6 1 110.16000 110.16000
这是否可以使用T-SQL实现?我尝试了一些不同的方法,例如将
id
加入id-1
,并尝试了使用update
和设置变量的顺序更新,但我无法让它工作。递归CTE可能是最好的方法。假设您的id
s没有间隙:
with cte as (
select id, multiplier, convert(float, col1) as col1, convert(float, col1 * multiplier) as col2
from table1
where id = 1
union all
select t1.id, t1.multiplier, cte.col2 as col1, cte.col2 * t1.multiplier
from cte join
table1 t1
on t1.id = cte.id + 1
)
select *
from cte;
他是一把小提琴
请注意,我将目标类型转换为
float
,这便于此类操作。如果愿意,可以将其转换回十进制。基本上,这需要一个聚合/窗口函数来计算列值的乘积。但是,SQL中不存在这样的set函数。我们可以用算术来解决这个问题:
select
id,
multiplier,
coalesce(min(col1) over() * exp(sum(log(multiplier)) over(order by id rows between unbounded preceding and 1 preceding)), col1) col1,
min(col1) over() * exp(sum(log(multiplier)) over(order by id)) col2
from table1
:
id | multiplier | col1 | col2
-: | ---------: | -----: | -----:
1 | 2 | 1.53 | 3.06
2 | 3 | 3.06 | 9.18
3 | 2 | 9.18 | 18.36
4 | 2 | 18.36 | 36.72
5 | 3 | 36.72 | 110.16
6 | 1 | 110.16 | 110.16
with cte as (
select col1, col2,
coalesce(min(col1) over() * exp(sum(log(multiplier)) over(order by id rows between unbounded preceding and 1 preceding)), col1) col1_new,
min(col1) over() * exp(sum(log(multiplier)) over(order by id)) col2_new
from table1
)
update cte set col1 = col1_new, col2 = col2_new