使用从上一个值到下一个填充值的值更新列

时间:2019-06-27 09:53:07

标签: mysql sql min next

我有一个表,其中包含每月的金额和上个月的金额。

每个月我都需要携带上一个月的金额(如果不存在)。

为更好地解释(并举例说明),我可能有以下数据;

Month,Amount,Previous
2019-01-01,100,0
2019-02-01,100,100
2019-03-01,100,null
2019-04-01,100,null
2019-05-01,100,200
2019-06-01,100,null

所以我想将100携带到三月和四月,然后将200携带到六月,所以看起来像这样;

Month,Amount,Previous
2019-01-01,100,0
2019-02-01,100,100
2019-03-01,100,100
2019-04-01,100,100
2019-05-01,100,200
2019-06-01,100,200

我只是空白,我知道有办法,但是头脑根本没有把它放在一起。

我认为这将涉及在同一张表上进行LEFT JOIN,并获得一个MIN月值,该值的日期大于上个月的月值,但不大于下一个月的值。

或者它将在WHERE子句和LEFT JOIN中进行子查询。

到目前为止,我已经管理了以下内容,但是它为每个先前的值(100和200)重复了5月和6月的行。

SELECT
    *
FROM
    table1 t1
    LEFT JOIN
        table1 t2 ON
            t1.month > t2.month
Month,Amount,Previous
2019-01-01,100,0
2019-02-01,100,100
2019-03-01,100,100
2019-04-01,100,100
2019-05-01,100,200
2019-05-01,100,100
2019-06-01,100,200
2019-06-01,100,100

3 个答案:

答案 0 :(得分:0)

drop table if exists t;
create table t
(Month date,Amount int,Previous int);
insert into t values
('2019-01-01',100,0),
('2019-02-01',100,100),
('2019-03-01',100,null),
('2019-04-01',100,null),
('2019-05-01',100,200),
('2019-06-01',100,null);

select t.*,
        case when previous is null then
            (select previous from t t1 where t1.month < t.month and t1.previous is not null order by month desc limit 1)
        else previous
        end as previousdownfilled
from t;

+------------+--------+----------+--------------------+
| Month      | Amount | Previous | previousdownfilled |
+------------+--------+----------+--------------------+
| 2019-01-01 |    100 |        0 |                  0 |
| 2019-02-01 |    100 |      100 |                100 |
| 2019-03-01 |    100 |     NULL |                100 |
| 2019-04-01 |    100 |     NULL |                100 |
| 2019-05-01 |    100 |      200 |                200 |
| 2019-06-01 |    100 |     NULL |                200 |
+------------+--------+----------+--------------------+
6 rows in set (0.00 sec)

其中case语句检查是否需要完成操作,相关的cub查询执行该操作。但是我怀疑应该在创建此表的代码中完成这项工作。

答案 1 :(得分:0)

您可以在此处使用Correlated Subquery。在子查询中,我们将ORDER BYLIMIT结合使用以获取前一个立即金额值。

SELECT
    t1.month, 
    t1.amount, 
    (SELECT t2.amount FROM table1 t2 
     WHERE t2.month < t1.month 
     ORDER BY t2.month DESC LIMIT 1) AS previous 
FROM
    table1 t1

答案 2 :(得分:0)

在MySL 8+中,您可以使用窗口功能。不幸的是,MySQL还没有实现最简单的方法-使用lag()选项的ignore nulls

但是您仍然可以很简单地做到这一点:

select month, amount, 
       max(previous) over (partition by grp) as previous
from (select t.*, count(previous) over (order by month) as grp
      from t
     ) t;