如何在 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 表的列中向下移动值?的主要内容,如果未能解决你的问题,请参考以下文章