2011-05-23 113 views
16

我想用一個正在運行的整數數字填充一個表列,所以我正在考慮使用ROWNUM。但是,我需要根據其他列的順序來填充它,例如ORDER BY column1, column2。也就是說,不幸的是,不可能的,因爲甲骨文不接受以下聲明:我該怎麼辦呢使用Oracle:使用ROWNUM和ORDER BY子句更新一個表列

WITH tmp AS (SELECT * FROM table_a ORDER BY column1, column2) 
UPDATE tmp SET sequence_column = rownum; 

所以:

UPDATE table_a SET sequence_column = rownum ORDER BY column1, column2; 

也不以下語句(以WITH子句中使用的嘗試)一個SQL語句,而不使用PL/SQL中的遊標迭代方法?

+2

一旦當語句完成時,另一個DML操作發生,'sequence_col umn'會出錯/過時。爲什麼不把sequence_column(和編號)放在視圖中 - 這總是正確的。 – 2011-05-23 07:24:39

+0

@Damien_The_Unbeliever我不知道我是否理解你,但是不需要擔心未來將記錄插入表中,因爲該列是唯一索引的,並且插入的腳本將保證將下一個運行號放入列中。只是在記錄被刪除時,列不再是順序的,需要重新排序。 – Lukman 2011-05-23 07:32:37

+0

@Lukman,我同意Damien。最好是在運行 – 2011-05-23 07:34:33

回答

26

這應該工作(對我的作品)

update table_a outer 
set sequence_column = (
    select rnum from (

      -- evaluate row_number() for all rows ordered by your columns 
      -- BEFORE updating those values into table_a 
      select id, row_number() over (order by column1, column2) rnum 
      from table_a) inner 

    -- join on the primary key to be sure you'll only get one value 
    -- for rnum 
    where inner.id = outer.id); 

或使用MERGE聲明。像這樣的東西。

merge into table_a u 
using (
    select id, row_number() over (order by column1, column2) rnum 
    from table_a 
) s 
on (u.id = s.id) 
when matched then update set u.sequence_column = s.rnum 
+0

Oracle返回錯誤:當我在'SET'子句中使用它時,'ORA-30483:窗口函數不允許在這裏'__ < – Lukman 2011-05-23 07:23:58

+0

請參閱我的更新。我用一張簡單的桌子試了一下。它會給你一個解決方案的想法 – 2011-05-23 07:31:38

+0

我執行了這個聲明,它現在仍在運行,差不多5分鐘。該表只有大約15K記錄,儘管如此緩慢奇怪.. – Lukman 2011-05-23 07:40:50

2
UPDATE table_a 
    SET sequence_column = (select rn 
          from (
           select rowid, 
             row_number() over (order by col1, col2) 
           from table_a 
          ) x 
          where x.rowid = table_a.rowid) 

但是,這不會是非常快,如達明指出的那樣,你必須重新運行每次該表中更改數據時,這一說法。

2

首先創建一個序列:使用序列更新後

CREATE SEQUENCE SEQ_SLNO 
    START WITH 1 
    MAXVALUE 999999999999999999999999999 
    MINVALUE 1 
    NOCYCLE 
    NOCACHE 
    NOORDER; 

表:

UPDATE table_name 
SET colun_name = SEQ_SLNO.NEXTVAL; 
+1

「ORDER BY」部分如何? – Lukman 2014-02-04 04:56:18

1

小幅盤整隻是增加AS RN

UPDATE table_a 
    SET sequence_column = (select rn 
          from (
           select rowid, 
             row_number() over (order by col1, col2) AS RN 
           from table_a 
          ) x 
          where x.rowid = table_a.rowid)