在sql行中填充序列

时间:2011-02-01 13:03:20

标签: sql-server oracle sequences

我有一个存储一组属性的表,并按顺序对它们进行排序。存在这样的可能性:可以从表中删除其中一个属性(行),并且应该压缩位置序列。

例如,如果我最初拥有这些值集:

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  2 | two    |   2 |
|  3 | three  |   3 |
|  4 | four   |   4 |
+----+--------+-----+

第二行被删除,所有后续行的位置应该更新以填补空白。结果应该是这样的:

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  3 | three  |   2 |
|  4 | four   |   3 |
+----+--------+-----+

有没有办法在单个查询中执行此更新?我怎么能这样做?

PS:我很欣赏SQLServer和Oracle的例子,因为系统应该支持两个引擎。谢谢!

更新:原因是允许用户随意修改位置,以及添加或删除新行。位置显示给用户,因此,这些位置应始终显示一致性序列(此序列必须存储,而不是按需生成)。

3 个答案:

答案 0 :(得分:4)

不确定是否有效,但对于Oracle,我会尝试以下方法:

update my_table set pos = rownum;

答案 1 :(得分:0)

这可行,但对于大型数据集可能不是最理想的:

SQL> UPDATE my_table t
  2     SET pos = (SELECT COUNT(*) FROM my_table WHERE id <= t.id);

3 rows updated

SQL> select * from my_table;

        ID NAME              POS
---------- ---------- ----------
         1 one                 1
         3 three               2
         4 four                3

答案 2 :(得分:0)

您真的需要序列值是连续的,还是只需要能够显示连续的值?最简单的方法是让实际序列变得稀疏,并根据顺序计算排名:

select id, 
       name, 
       dense_rank() over (order by pos) as pos,
       pos as sparse_pos 
from my_table

(注意:这是特定于Oracle的查询)

如果你首先使位置稀疏,这甚至会使重新排序变得更容易,因为你可以将每个新位置放在两个现有位置的中间位置。例如,如果您有一个这样的表:

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    | 100 |
|  2 | two    | 200 |
|  3 | three  | 300 |
|  4 | four   | 400 |
+----+--------+-----+

当将ID 4移动到位置2时,您只需将位置更改为150。


进一步解释:

使用上面的示例,用户最初会看到以下内容(因为您正在屏蔽该位置):

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  2 | two    |   2 |
|  3 | three  |   3 |
|  4 | four   |   4 |
+----+--------+-----+

当用户通过您的界面指示位置4中的记录需要移动到位置2时,您将ID 4的位置更新为150,然后重新运行查询。用户看到了这一点:

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  4 | four   |   2 |
|  2 | two    |   3 |
|  3 | three  |   4 |
+----+--------+-----+

这不起作用的唯一原因是用户是否直接在数据库中编辑数据。虽然,即使在这种情况下,我也倾向于使用这种解决方案,通过视图和替代触发器。