Col1 Col2 12 a 12 c 12 b
如果我编码:从A中选择*;
结果是:
Col1 Col2 12 a 12 b 12 d
我想获取数据是:
Col1 Col2 12 a 12 c 12 b
如何获取数据不排序?
解决方法
您可能会发现this answer I wrote earlier提供信息.
在Postgresql中,对行的UPDATE可以将它们移动到表中的不同位置,从而改变它们返回的顺序.后台autovacuum进程以及VACUUM和CLUSTER等各种其他操作也可以.
所以你绝不能依赖“默认”排序.如果要为行提供某种顺序,则必须有一个可以对其进行排序的键.
如果您创建了一个没有密钥的表,现在意识到它应该有一个,您可以通过使用ctid系统列从该情况中恢复.不要依赖于此用于生产用途,它是一个系统内部列,用户只能看到紧急恢复和诊断目的.首先,查看物理磁盘排序是否实际上是您想要的顺序:
SELECT row_number() OVER () AS mytable_id,* FROM mytable ORDER BY ctid;
如果是,则可以添加一个新的键列,该键预先设置为以磁盘行顺序应用的自动递增键.有两种方法可以做到这一点.最安全的是:
BEGIN; LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE; ALTER TABLE mytable RENAME TO mytable_old; CREATE TABLE mytable (id SERIAL PRIMARY KEY,LIKE mytable_old INCLUDING ALL); INSERT INTO mytable SELECT row_number() OVER () AS id,* FROM mytable_old ORDER BY ctid; SELECT setval('mytable_id_seq',(SELECT max(id)+1 FROM mytable)); COMMIT;
然后,一旦你确定你对结果感到满意,DROP TABLE mytable_old;.看这个演示:http://sqlfiddle.com/#!12/2cb99/2
一种快速简便但不太安全的方法是创建列并依赖Postgresql从头到尾重写表:
ALTER TABLE mytable ADD COLUMN mytable_id SERIAL PRIMARY KEY;
绝对不能保证Postgresql会按顺序分配ID,但实际上它会这样做.见this SQLFiddle demo.
请注意,当您使用SEQUENCE(这是SERIAL列创建的)时,您可能会发现一些行为.当您一次插入多行时,行可能不一定按照您期望的顺序获得分配的ID,并且它们可能以与分配ID的顺序不同的顺序“显示”(变为可见)并插入此外,如果事务回滚,生成的ID将永远丢弃,因此您会在编号中出现空白.如果您希望数据库速度很快,这是非常好的,但如果您想要无间隙编号,这并不理想.如果这就是您所需要的,请搜索“postgresql gapless sequence”.