更新表中的一个字段,以引用同一个表Oracle上的另一个字段

时间:2013-10-07 08:03:05

标签: sql oracle sql-update

我需要使用顺序值(例如001,002,002)更新varchar2字段,以引用同一个表中的另一个字段entity_id。我需要它,如果例如我在两个不同的行上有相同的entity_id,那么顺序值应该是相同的。

示例输出:

Entity_id      Seq_field
1234           001
1234           001
4567           002
4567           002
3412           003

我尝试过rownum但是它为每个entity_id提供了不同的值,当然这些值没有尾随零。请帮忙。

2 个答案:

答案 0 :(得分:3)

merge into the_table
using
(
  select rowid as rid,
         entity_id, 
         to_char(dense_rank() over (order by entity_id), 'FM00000') as seq
  from foo
) t on (the_table.rowid = t.rid)
when matched 
  then update set seq_field = t.seq;

如果你想为每个entity_id开始一个新的序列,你需要稍微改变一下这个陈述:

merge into foo
using
(
  select rowid as rid,
         entity_id, 
         to_char(row_number() over (partition by entity_id order by null), 'FM00000') as seq
  from foo
) t on (foo.rowid = t.rid)
when matched 
  then update set seq_field = t.seq;

请注意,我使用row_number()而不是dense_rank()partition by entity_id来重新使用entity_id的新值重新编号。如果您有另一列确定一个entity_id的“订单”,那么您可以将null中的order by null替换为该列,例如order by created_at

答案 1 :(得分:1)

你有多少条记录?下面是我提出的解决方案,但不能很好地处理大量数据。

CREATE TABLE tab (entity_id NUMBER, seq_field VARCHAR2(3));

INSERT INTO tab VALUES (1234, NULL);
INSERT INTO tab VALUES (1234, NULL);
INSERT INTO tab VALUES (4567, NULL);
INSERT INTO tab VALUES (4567, NULL);
INSERT INTO tab VALUES (3412, NULL);

UPDATE tab t SET seq_field = (
  SELECT LPAD(rnk, 3, '0')
    FROM (
      SELECT entity_id, seq_field, DENSE_RANK() OVER (ORDER BY entity_id) AS rnk
        FROM tab
    ) t2
  WHERE t2.entity_id = t.entity_id AND rownum = 1
);

检查SQLFiddle:http://sqlfiddle.com/#!4/3959d/1

考虑在您的问题中添加SQLORACLE标记,猜测您会得到更多关注,也许是更好的解决方案。