【问题标题】:Accessing prior rows and divide its value by current row访问先前的行并将其值除以当前行
【发布时间】:2016-04-27 02:47:28
【问题描述】:

我有下面的行,我想访问前一行并将其值除以当前行。对于每一行,我需要计算 Vi 值,这个 Vi 值等于 Vi-1/Vi,这意味着:

给定表格

Table T
id value out
1  100
2  200
3  10  
4  50 

我想生成这些值

V1 = 100
V2= 100/200 = 0.5
V3 = 0.5/10 = 0.05
V4 = 0.05/50 = 0.001

所以最后我想要以下输出:

id value out
1  100   100
2  200   0.5
3  10    0.05
4  50    0.001

我尝试将聚合函数 SUM 与 OVER() 一起使用,但我不知道如何解决这个问题,因为我需要除而不是求和

    SELECT  id, value, SUM(value) OVER(ORDER BY id ROWS BETWEEN 
                                       1 PRECEDING AND 1 PRECEDING ) / value as out
    FROM T

样本数据:

CREATE TABLE t(
    id      INT,
    value   INT
);
INSERT INTO t VALUES
    (1, 100), (2, 200), (3, 10), (4, 50);

【问题讨论】:

  • 不能使用 T-SQL 是什么意思?
  • 我的意思是我不能使用 CREATE 过程,CREATE 函数...
  • 有趣的问题!
  • 添加了示例数据的创建。

标签: sql-server divide cumulative-sum


【解决方案1】:

可惜SQL没有Product,不过用cte应该很简单。如果id被索引了,性能应该还不错

DECLARE @T table (id int identity(1,1) primary key, value int)
INSERT @T VALUES (100), (200), (10), (50)

;WITH cte AS
(
    SELECT id, value, CAST(value AS decimal(20,4)) AS out FROM @T WHERE id = 1
    UNION ALL SELECT T.id, T.value, CAST(cte.out / T.value AS decimal(20,4)) FROM cte INNER JOIN @T T ON cte.id = T.id - 1
)
SELECT * FROM cte

【讨论】:

  • 请查看用户问题的输出
  • @TheGameiswar 谢谢
  • 谢谢,我明白了。您使用递归 CTE,您从 id = 1 的行开始,然后将当前行与下一行 (T.id-1) 连接,然后继续执行直到到达最后一行 (id=4),不能再加入了
  • @RoniCastro 注意:加入条件假设 id 是连续的。
  • @Eric 没关系,我会使用函数 ROW_NUMBER() 来生成一个连续的id
猜你喜欢
  • 2019-09-16
  • 2022-08-23
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
相关资源
最近更新 更多