0

我有一些 SQL 表,比如单列 c1:

c1
10
3
1
10
5

现在,我想发出一个 SQL 命令(不是我的 DBMS 的某些操作,我故意没有提到),这导致我的表是:

c1 记录索引
10 0
3 1
1 2
10 3
5 4

很简单……这可以吗?显然,你事先并不知道表的长度,所以没有 SQL 插入或类似的技巧。

注意:我想要一个一般性的答案,但要具体一点 - 我正在使用MonetDB

4

2 回答 2

2

关系数据库中没有“行索引”之类的东西(请注意,关系数据库包含行,而不是“记录”),但是如果您可以找到用于对结果进行排序的列,则可以使用窗口功能:

select c1,
       row_number() over (order by some_column) as record_index
from the_table
order by record_index;

(你没有指定你的DBMS,上面是ANSI SQL)

编辑

如果您没有要排序的列,则可以尝试按常量值排序,这将带回“无序”的行:

select record_index,
       row_number() over (order by 42) as record_index
from the_table
order by record_index;

但同样:没有“自然”的行顺序。磁盘上可能有一个,但很可能不是在检索期间使用的那个 - 特别是当表没有聚集索引时(Oracle 默认不使用聚集索引,Postgres 没有它们完全)。

在检索数据时,DBMS 也可能会应用额外的优化。Oracle、Postgres 和我相信 SQL Server 也可以例如“跳跃”来自不同会话的表扫描,以优化从磁盘的物理读取。在这种情况下,即使硬盘上的物理布局没有改变,两个并发选择也会显示不同的“顺序”。

然后由于更新而对物理存储进行了更改(例如,如果一行不再适合块,因为它的大小增加了)。

于 2014-02-18T12:31:32.727 回答
0

@a_horse_with_no_name 的回答启发...:

SELECT 
  c1, 
  row_number() OVER (ORDER BY dummy)-1 AS record_index
FROM 
  (SELECT 
    c1,
    42 AS dummy 
  FROM t1
) AS t1_augmented;

(当然要注意 row_number() 的结果是从 1 开始的。)

于 2014-02-27T10:06:15.073 回答