如何在 Oracle 表的列中向下移动值?

Posted

技术标签:

【中文标题】如何在 Oracle 表的列中向下移动值?【英文标题】:How do you shift values down in a column in an Oracle table? 【发布时间】:2016-12-09 10:13:41 【问题描述】:

给定以下oracle数据库表:

小组修订意见 1 1 1 1 2 2 1 空空 2 1 1 2 2 2 2 3 3 2 4 4 2 空空 3 1 1 3 2 2 3 3 3 3 空空

我想在其组内将评论列相对于版本向下移动一级,以便得到下表:

小组修订意见 1 1 无 1 2 1 1 无 2 2 1 无 2 2 1 2 3 2 2 4 3 2 无 4 3 1 无 3 2 1 3 3 2 3 无 3

我有以下疑问:

合并到 example_table t1 使用 example_table t2 在 ( (t1.revision = t2.revision+1 或 (t2.revision = ( 选择最大值(t3.revision) FROM example_table t3 哪里 t3.group = t1.group ) AND t1.revision 为空) ) 和 t1.group = t2.group) 匹配时更新集 t1.comment = t2.comment;

这完成了大部分工作(仍然需要一个单独的查询来覆盖修订 = 1),但它非常慢。

所以我的问题是,我如何在这里尽可能有效地使用 Max 来提取每个组的最高修订版?

【问题讨论】:

【参考方案1】:

我会使用lag 而不是max

create table example_table(group_id number, revision number, comments varchar2(40));
insert into example_table values (1,1,1);
insert into example_table values (1,2,2);
insert into example_table values (1,3,null);
insert into example_table values (2,1,1);
insert into example_table values (2,2,2);
insert into example_table values (2,3,3);
insert into example_table values (2,4,null);

select * from example_table;

merge into example_table e
using (select group_id, revision, comments, lag(comments, 1) over (partition by group_id order by revision nulls last) comments1 from example_table) u
on (u.group_id = e.group_id and nvl(u.revision,0) = nvl(e.revision,0))
when matched then update set comments = u.comments1;

select * from example_table;

【讨论】:

是的,这似乎有效。所以这个答案加上这个docs.oracle.com/cd/B28359_01/server.111/b28286/…(关于分析函数的部分)帮助了我很多。 UPDATE 语句不起作用 - WITH 子句不能在 UPDATE 之前,它需要在它之后。并且在 MERGE 的 ON 条件下使用 NVL 是有风险的 - 如果 0 是修订的合法值之一怎么办?最好写“或 u.revision 为空而 v.revision 为空”。 (实际上,如果表有一个主键会更好!)否则这是正确的答案,干得好! @mathguy 当然不会。在构建答案时,这只是我的一团糟。正确的答案是合并而不是更新。 对 - 无论如何,在这种情况下,MERGE 是正确的答案。

以上是关于如何在 Oracle 表的列中向下移动值?的主要内容,如果未能解决你的问题,请参考以下文章

如果同一表的另一列中存在值,如何找到对应的列值

如何在 Oracle 表的 varchar 列中的第二个和第四个字符之后插入“/”

如何在 DolphinDB 表的列中选择唯一元素?

VBA代码在数据透视表旁边的列中向下拖动公式

oracle如何快速判断表中的某列是不是有空值

如何计算 ID 在不同表的列中出现的次数