基于Oracle数据库中的两列增加列值

时间:2018-08-22 00:57:00

标签: database oracle function

我有一个表Test,其结构如下:

Id  CID RO   Other Columns
1   111  2
2   111  1
3   111  6
4   111  6
5   111  8
6   111  5
7   101  4
8   101  4
9   101  3   

RO中的结果顺序应如下所示: ->对于一个CID,RO的升序应以1、2、3、4等代替(RO)

RO栏中的最终订单:

(RO列的值已替换)

 Id  CID RO  (New) RO Other Columns
    1   111  2   2
    2   111  1   1 
    3   111  6   4
    4   111  6   5
    5   111  8   6
    6   111  5   3
    7   101  4   2
    8   101  4   3
    9   101  3   1 

表中有数百个cid。请让我知道这是否可以使用某些Oracle函数在单个查询中实现或需要编写某些过程。任何线索或示例都将有所帮助。

谢谢

2 个答案:

答案 0 :(得分:2)

可以使用分析函数ROW_NUMBER()计算NEW_RO列:

select ... ,
       row_number() over (partition by cid order by ro) as new_ro  [, ...]

在您的数据中,同一CID中的RO具有联系。在这种情况下,您是否在意哪一行获得NEW_RO值?例如,如果在相同RO的情况下,您还想按ID(进一步)订购,则可以将上面的更改为

select ... ,
       row_number() over (partition by cid order by ro, id) as new_ro  [, ...]

编辑:我错过了您需要使用NEW_RO值更新RO值的事实。解析函数不能用在UPDATE语句中(无论如何不能直接使用); MERGE语句是解决此问题的完美选择:

merge into test
  using ( select id, 
                 row_number() over (partition by cid order by ro, id) as new_ro 
          from   test
        ) s
        on (test.id = s.id)
when matched then update set ro = s.new_ro
;

答案 1 :(得分:2)

在对@mathguy答案的评论中解决后续问题。如果您有一个查询正在生成所需的新值,并且希望快速编写更新,那么我想使用merge:

MERGE INTO your_table target
USING (your_query_here) source
ON (Target.ID = Source.ID)
WHEN MATCHED THEN 
UPDATE SET Target.column = Source.new_value

https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm#SQLRF01606

MERGE可以做得更多,但是在这种“纠正数据”情况下,我发现它很方便。