SQL-Oracle 使用 LAG() 从自身更新表

标签 sql oracle sql-update

假设我们有一张这样的表:

| 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/

相关文章:

mysql - 为什么触发器不在架构范围内?

asp.net - Oracle.DataAccess.dll 虽然存在但无法定位

PostgreSql:无法在 UPDATE 中使用聚合函数

MySQL 错误 1064 - 我瞎了吗?奇怪的错误

sql - Max() 的自定义顺序

mysql - 将 Office Open XML (OOXML) 文件作为 blob 插入 MySQL

sql - Oracle create table with foreign key 错误 - 标识符无效

MySQL:通过感知哈希相似性对结果进行分组

sql - 与 Oracle 动态 SQL 斗争

SQL Server 更新触发器,仅获取修改的字段