mysql - 通过 LEAD/LAG 或递归 CTE 更新?

标签 mysql sql sql-server

有一个表保存日期和帐户余额。 但是,某些日期无法使用余额。 假设当日期不可用时余额不会改变。 如何更新所有日期的余额信息?

这是一个例子: 表 D 包含所有有效日期。

2000-01-01
2000-01-02
2000-01-03
2000-01-04
2000-01-05
2000-01-06
2000-01-07
2000-01-08
2000-01-09

表 A 包含日期和帐户余额。

2000-01-02  $100
2000-01-05  $200
2000-01-09  $700

最终,我想生成一个像这样的表格:

2000-01-01  null
2000-01-02  $100
2000-01-03  $100
2000-01-04  $100
2000-01-05  $200
2000-01-06  $200
2000-01-07  $200
2000-01-08  $200
2000-01-09  $700

我考虑过以下问题:

  • 领先和滞后,
  • 递归 CTE

但是,似乎都不适合这种场景。

最佳答案

SQL Server 不支持 LAG()LAST_VALUE()IGNORE NULLS 选项。这其实是最简单的方法。

相反,您可以使用APPLY:

select d.*, a.balance
from dates d outer apply
     (select top (1) a.*
      from a
      where a.date <= d.date
      order by a.date desc
     ) a;

或者使用相关子查询的等效方法:

select d.*,
       (select top (1) a.*
        from a
        where a.date <= d.date
        order by a.date desc
        fetch first 1 row only
       )
from dates d;

这适用于 MySQL 和 SQL Server,但需要注意的是 MySQL 中需要 LIMIT

也就是说,如果您有大量数据(这在“日期”的粒度上不太可能),那么两步窗口函数可能是更好的解决方案:

select ad.date,
       max(ad.balance) over (partition by grp) as balance
from (select d.date, a.balance,
             count(a.date) over (order by d.date) as grp
      from dates d left join
           a
           on d.date = a.date
     ) ad;

子查询为每个余额值和以下日期分配一个“组”。然后,该“组”用于分配外部查询中的余额。

此版本可在 MySQL 或 SQL Server 中运行。

关于mysql - 通过 LEAD/LAG 或递归 CTE 更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58109333/

相关文章:

mysql - 具有多个多对多关系的数据库的高效设计

mysql - 如何在 UPDATE 查询中执行三个表 JOIN?

javascript - fabric js 从 mysql 数据库加载单个对象到 Canvas

php - 高效的 friend 建议sql查询,无需使用php

sql-server - 如何在 SQL Server 中使用 alter 设置列的默认值?

mysql - 如何仅在 mysql 中获取最小组行?

sql - 连接内的相关子查询?

php - 显示值为零的行

c# - 600K 记录的数据库或平面文件?

sql - 有没有办法在一个 SELECT 语句中执行此操作?使用分组依据