假设我们有一张这样的表:
| Year | Month | Day | ID_Office | Operations | Operations yesterday |
|------|-------|-----|-----------|------------|----------------------|
| 2016 | 12 | 31 | 9555 | 500 | 0 |
| 2017 | 1 | 1 | 9555 | 600 | 0 |
| 2017 | 1 | 2 | 9555 | 750 | 0 |
| 2017 | 1 | 3 | 9556 | 800 | 0 |
我想使用上一行中的“操作”来更新“昨天的操作”中的值。所以结果表一定是这样的:
| Year | Month | Day | ID_Office | Operations | Operations yesterday |
|------|-------|-----|-----------|------------|----------------------|
| 2016 | 12 | 31 | 9555 | 500 | 0 |
| 2017 | 1 | 1 | 9555 | 600 | 500 |
| 2017 | 1 | 2 | 9555 | 750 | 600 |
| 2017 | 1 | 3 | 9556 | 800 | 0 |
我将以下代码与函数 LAG() 一起使用,但它没有更新正确的值。
Update table1 F1
Set f1.operations_yesterday =
(Select LAG(f1.operations, 1, 0) OVER(ORDER BY year, month, day)
From table1 F2
Where
F1.year= F2.year And
F1.month= F2.month And
F1.day= F2.day);
您能否从我的代码中给我一些关于到底哪里错误的建议? 我在“Insert Into”语句上使用 lag() 函数取得了成功,但在这种情况下,我必须提供 Update 语句解决方案。
注意: 请注意,可以有三个以上的字段进行排序。我只举了年、月、日作为例子,但还有更多与日期无关的字段。 此外,重要的是要详细说明并非每天都有值(value)。
提前谢谢您!
最佳答案
不建议冗余存储数据。然而...
您想要将前一天的数据存储在记录中。您假设每天都有一条记录,因此前一天也将是按日期排序的之前记录。但这些知识并没有真正的帮助,因为选择前一天比选择之前的记录要容易得多。
非常奇怪的是,您分别存储日、月和年,而不仅仅是日期。我不知道你想用这个达到什么目的。我们必须笨拙地转换它。
update table1 today
set operations_yesterday =
(
select operations
from table1 yesterday
where to_date(yesterday.year * 10000 + yesterday.month * 100 + yesterday.day, 'yyyymmdd')
= to_date(today.year * 10000 + today.month * 100 + today.day, 'yyyymmdd') - 1
);
如果您存储日期,那就很简单:
update table1 today
set operations_yesterday =
(select operations from table1 yesterday where yesterday.date = today.date - 1);
如果您想要 0 而不是没有昨天的 null,请添加 COALESCE
(或 Oracle 的 NVL
)。
关于SQL-Oracle 使用 LAG() 从自身更新表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46235825/