sql - SQL计算总体成功率: Recursive CTE or Alternative Approach?

标签 sql sql-server window-functions

作为输入,我有 3 个字段:

  • Column_A:按时间顺序表示调查的步骤
  • Column_B:代表参与调查步骤的人数
  • Column_C:代表成功完成此特定调查步骤的人数 (B >= C)

现在我需要计算一个新的Column_D:该列需要代表参与者的总数,在所有前面的步骤之后仍然保持成功。因此,这个数字充其量只能保持不变,或者在每一步之后减少,以防参与者不成功。

在 Excel 中,这有点简单,因为我会计算(除了第 1 行): 前一行的 Value_D - (Value_B - Value_C)。

我知道 SQL 中的滞后和超前,但是如何考虑同一列的前一行的计算?它以某种方式起作用吗?我需要编写递归 CTE 之类的代码吗?

我认为大问题是这样的:行数 (Column_A) 不一样,所以我不能将几个 CTE 粘合在一起。

<表类=“s-表”> <标题> Column_A Column_B Column_C Column_D <正文> 0 35 35 35 1 35 35 35 2 35 34 34 3 34 33 33 4 33 30 30 5 33 31 28 6 33 33 28

我尝试了以下方法,但显然它返回了错误的结果,因为它没有考虑前面的计算。

SELECT [Column_A]
      ,[Column_B]
      ,[Column_C]
      , CASE WHEN [Column_A] = 0 
             THEN [Column_B]
             ELSE LAG([Column_C], 1, 0) OVER (PARTITION BY 1 
                                              ORDER     BY [Column_A] ASC) - ([Column_B] - [Column_C])
        END AS [Column_D]
FROM dataset

最佳答案

您可以组合两个窗口函数:

  • FIRST_VALUE ,收集第一个“Column_D”值
  • SUM ,收集“Column_B”和“Column_C”之间的运行差异

然后从第一个窗口函数中减去第二个窗口函数。

SELECT *, FIRST_VALUE(Column_D) OVER(ORDER BY Column_A ROWS UNBOUNDED PRECEDING) - 
          SUM(Column_B - Column_C) OVER(ORDER BY Column_A ROWS UNBOUNDED PRECEDING) 
FROM tab

输出:

<表类=“s-表”> <标题> Column_A Column_B Column_C Column_D (无列名称) <正文> 0 35 35 35 35 1 35 35 35 35 2 35 34 34 34 3 34 33 33 33 4 33 30 30 30 5 33 31 28 28 6 33 33 28 28

查看演示 here .

关于sql - SQL计算总体成功率: Recursive CTE or Alternative Approach?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76308208/

相关文章:

sql - 如何创建使用 INSERT 、 DELETE 、 UPDATE 事件的触发器

sql - Postgresql 更新左连接

sql-server - Azure逻辑应用程序: How do I pass a single For Each variable to an Execute Stored Procedure step?

SQL:索引/分组具有双重清除条件的事件

postgresql - 在 Postgresql 中创建一个多列作为参数的函数

php - SQL 语句中的多个 BETWEEN 和 LIMIT 运算符

mysql - Where 子句中的未知列

sql-server - 如何一次为多个表启用标识插入?

sql-server - go-mssql 设置连接超时

sql-server - ROW_NUMBER 与 COUNT(1) 个?