我有一个表,其中包含每月的金额和上个月的金额。
每个月我都需要携带上一个月的金额(如果不存在)。
为更好地解释(并举例说明),我可能有以下数据;
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
答案 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 BY
与LIMIT
结合使用以获取前一个立即金额值。
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;