1

我有一个表结构

编号 | col1 | col2
 1 | 1 | val1
 2 | 2 | val2
 3 | 3 | val3 --
 4 | 4 | val4
 5 | 5 | val1
 6 | 6 | val6

我想执行删除操作来删除其中一行(比如 id=3),这样我的数据就会变成:

编号 | col1 | col2
 1 | 1 | val1
 2 | 2 | val2
 4 | 4 | val4
 5 | 5 | val1
 6 | 6 | val6

但我希望它像

编号 | col1 | col2
 1 | 1 | val1
 2 | 2 | val2
 4 | 3 | val4
 5 | 4 | val1
 6 | 5 | val6

我希望我的 col1 始终按顺序排列,而与其他列无关。关于如何去做的任何建议。只能在一个更新查询中完成吗?我使用 POSTGRESQL 作为我的数据库并使用 C# 进行编码。我在数据库中有大约 1000 行。请帮帮我。

4

3 回答 3

2

如果它是预定的操作,例如每天一次,那么您可以保留该有序列。如果不摆脱它并在查询中执行它:

select
    id,
    row_number() over(order by id) col1,
    col2
from t
于 2013-06-06T11:52:54.637 回答
0

你真的需要那个 col1 在你的桌子上吗?如果不是(例如,您使用 id 列保持排序),那么您可以在查询中使用 rank() 函数来返回动态计算的顺序排序。带表:

id | col2
 1 | val1
 2 | val2
 4 | val4
 5 | val5
 6 | val6

这个查询:

select id, rank() over (order by id), col2 from test

返回

id | col1 | col2
 1 |  1   | val1
 2 |  2   | val2
 4 |  3   | val4
 5 |  4   | val5
 6 |  5   | val6

这可以为您节省大量维护该列的麻烦,并且可以在某些情况下提供更好的性能,例如并发写入,因为受影响的行数较少。

于 2013-06-06T13:25:52.900 回答
0

如果它是一个选项,您可以使用触发器自动执行此操作。就像是:

create or replace function maintain_sort_idx() returns trigger as $$
begin
  update yourtable
  set col1 = col1 - 1
  where col1 > old.col1;
  return null;
end;
$$ language plpgsql;

create trigger maintain_sort_idx after delete on yourtable
for each row execute procedure maintain_sort_idx();

请注意,它不是防弹的,例如,如果您同时删除多行,它可能会也可能不会按预期工作。为了使其防弹,您需要修改更新查询,以便它col1 = row_number() over (...) where col1 <> row_number() over (...)使用您用来维护排序列的任何适当标准进行设置。(您的示例数据会建议 id,但我假设您有一个单独的列,例如更相关的 parent_id。)

于 2013-06-06T12:07:12.247 回答