0

我需要参考同一张表上的另一个字段 entity_id 来更新具有顺序值的 varchar2 字段,例如 001、002、002。我需要这样,例如,如果我在两个不同的行上有相同的 entity_id,那么顺序值应该是相同的。

示例输出:

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

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

4

2 回答 2

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 的“顺序”,那么您可以将nullin替换order by null为该列,例如order by created_at

于 2013-10-07T08:30:52.193 回答
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标签,猜想您会得到更多关注,也许是更好的解决方案。

于 2013-10-07T08:22:48.967 回答