是否可以更改Postgres中列的自然顺序?

postgresql

27079 观看

8回复

19601 作者的声誉

是否可以在Postgres 8.1中更改列的自然顺序?

我知道您不应该依赖列顺序-这对我正在做的事情不是必不可少的 -我只需要它可以使一些自动生成的内容以更令人愉悦的方式出现,从而使字段顺序与所有从pgadmin到后端再到前端。

作者: rjmunro 的来源 发布者: 2008 年 9 月 24 日

回应 (8)


0

95805 作者的声誉

不幸的是,不是,不是。列顺序完全取决于Postgres。

作者: Nick Johnson 发布者: 24.09.2008 10:40

1

213820 作者的声誉

在查询中指定列顺序是唯一可靠(合理)的方法。就是说,您通常可以通过更改表来获得不同的排序,如下例所示,因为通常(不保证返回)列的顺序是将它们添加到表的顺序。

postgres=# create table a(a int, b int, c int);
CREATE TABLE
postgres=# insert into a values (1,2,3);
INSERT 0 1
postgres=# select * from a;
 a | b | c
---+---+---
 1 | 2 | 3
(1 row)

postgres=# alter table a add column a2 int;
ALTER TABLE
postgres=# select * from a;
 a | b | c | a2
---+---+---+----
 1 | 2 | 3 |
(1 row)

postgres=# update a set a2 = a;
UPDATE 1
postgres=# alter table a drop column a;
ALTER TABLE
postgres=# alter table a rename column a2 to a;
ALTER TABLE
postgres=# select * from a;
 b | c | a
---+---+---
 2 | 3 | 1
(1 row)

postgres=#
作者: Vinko Vrsalovic 发布者: 24.09.2008 10:42

4

0 作者的声誉

正如其他答案所述,您不能更改列的顺序,这取决于postgres。您可以(并且应该!)用视图解决问题。就您的报告查询而言,它看起来就像一个表。就像是:

create view my_view as
  select * from my_table
  order by some_col;
作者: Please delete this account 发布者: 24.09.2008 12:14

16

16811 作者的声誉

如果您的数据库不是很大,并且您可以承受一些停机时间,则可以:

  1. 禁用对数据库的写访问,
    这是必不可少的,否则开始下一个点之后的所有更改都将丢失
  2. pg_dump --create --column-inserts databasename > databasename.pgdump.sql
  3. CREATE TABLE在databasename.pgdump.sql中编辑适当的语句
    如果文件对您的编辑器来说太大,只需使用split命令将其拆分,编辑,然后使用cat
  4. drop database databasename
    您确实有最近的备份,以防万一?
  5. psql --single-transaction -f databasename.pgdump.sql
    如果你不使用--single-transaction它会很慢

如果使用所谓的大对象,请确保它们包含在转储中。我不确定它们是否默认为8.1。

作者: Tometzky 发布者: 24.09.2008 02:25

22

292 作者的声誉

决定

实际上,您可以直接更改列顺序,但是我几乎不建议这样做,如果决定这样做,则应非常小心。

例如。

#CREATE TABLE测试(a int,b int,c int);
#插入测试值(1,2,3);
#SELECT * FROM test;
 一个| b | C
--- + --- + ---
 1 | 2 | 3
(1列)

现在需要技巧的是,您需要使用postgres用户连接到数据库,以便可以修改系统表。

#在pg_class中选择relname,relfilenode,其中relname ='test';
 relname | relfilenode
--------- + -------------
 test_t | 27666
(1列)

#从pg_attribute中选择attrelid,attname,attnum,其中attrelid = 27666;
 attrelid | 姓名| Attnum
---------- + ---------- + --------
    27666 | tableoid | -7
    27666 | cmax | -6
    27666 | xmax | -5
    27666 | cmin | -4
    27666 | xmin | -3
    27666 | ctid | -1
    27666 | b | 1个
    27666 | 一个| 2
    27666 | c | 3
(9列)

attnum是唯一列,因此在修改列号时需要使用一个临时值:

#更新pg_attribute SET attnum = 4 WHERE attname ='a'AND attrelid = 27666;
更新1
#更新pg_attribute SET attnum = 1哪里attname ='b'AND attrelid = 27666;
更新1
#更新pg_attribute SET attnum = 2 WHERE attname ='a'AND attrelid = 27666;
更新1

#SELECT * FROM test;
 b | 一个| C
--- + --- + ---
 1 | 2 | 3
(1列)

同样,由于这是数据库系统表的问题,如果您确实需要执行此操作,请格外小心。

从postgres 8.3开始,此功能已开始运行,并且在以前的版本中,您的里程可能会有所不同。

作者: Russell 发布者: 18.03.2009 03:06

8

388550 作者的声誉

我曾在2007年的pgsql-admin中问过这个问题。汤姆·莱恩本人宣称改变目录中的顺序实际上是不可行的。

澄清:这适用于使用本工具的用户。并不意味着,它无法实现。海事组织,应该。
对于Postgres 12仍然适用。

作者: Erwin Brandstetter 发布者: 16.09.2011 01:02

0

202 作者的声誉

您可以通过创建新表并按希望它们出现的顺序选择旧表中的列来获得所需的列顺序:

CREATE TABLE test_new AS SELECT b, c, a FROM test;
SELECT * from test_new;
 b | c | a 
---+---+---
 2 | 3 | 1
(1 row)

请注意,这仅复制数据,而不复制修饰符,约束,索引等。

一旦按照您想要的方式修改了新表,就放下原始表并更改新表的名称:

BEGIN;
DROP TABLE test;
ALTER TABLE test_new RENAME TO test;
COMMIT;
作者: Alex Willison 发布者: 30.11.2016 09:28

0

826 作者的声誉

我想要一样。是的,现在订购它是必不可少的,但它以错误的方式给我带来了麻烦:)

我要解决的问题如下。

这种方法将确保您保留所有现有数据,

  1. 使用所需的顺序和临时名称创建表的新版本。
  2. 将所有数据从现有表插入该新表中。
  3. 放下旧桌子。
  4. 将新表从“临时名称”重命名为“专有名称”。
  5. 重新添加您以前拥有的所有索引。
  6. 重置ID序列以获得主键增量。

当前表顺序:

id, name, email

1.使用临时名称使用所需的顺序创建表的新版本。

在此示例中,我想email成为之前name

CREATE TABLE mytable_tmp
(
  id SERIAL PRIMARY KEY,
  email text,
  name text
);

2.将所有数据从现有表插入到该新表中。

INSERT INTO mytable_tmp   --- << new tmp table
(
  id
, email
, name
)
SELECT
  id
, email
, name
FROM mytable;  --- << this is the existing table

3.放下旧桌子。

DROP TABLE mytable;

4.将新表从“临时名称”重命名为“专有名称”。

ALTER TABLE mytable_tmp RENAME TO mytable;

5.重新添加您以前拥有的所有索引。

CREATE INDEX ...

6.重置ID序列以增加主键。

SELECT setval('public.mytable_id_seq', max(id)) FROM mytable;
作者: Turgs 发布者: 01.02.2018 11:48
32x32