我尝试了以下内容,但我没有成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
答案 0 :(得分:86)
PostgreSQL目前定义了列 订单基于
attnum
列pg_attribute
表。唯一的办法 更改列顺序是通过 重新创建表格,或通过添加 列和旋转数据,直到你 达到理想的布局。
这非常弱,但在他们的辩护中,在标准SQL中,也没有重新定位列的解决方案。支持更改列的序号位置的数据库品牌正在定义SQL语法的扩展。
另一个想法是:我可以定义VIEW
,指定列的顺序,不改变基表中列的物理位置。
答案 1 :(得分:21)
这篇文章很老,可能已经解决,但我遇到了同样的问题。我通过创建指定新列顺序的原始表的视图来解决它。
从这里我可以使用视图或从视图中创建一个新表。
CREATE VIEW original_tab_vw AS SELECT a.col1, a.col3, a.col4, a.col2 FROM original_tab a WHERE a.col1 IS NOT NULL --or whatever
SELECT * INTO new_table FROM original_tab_vw
重命名或删除原始表,并将新表的名称设置为旧表。
答案 2 :(得分:16)
虽然在必须绝对更改列顺序并且正在使用外键时重新排列列的一个笨拙的选项是首先使用数据转储整个数据库,然后只转储模式(pg_dump -s databasename > databasename_schema.sql
)。接下来编辑模式文件以根据需要重新排列列,然后从模式重新创建数据库,最后将数据还原到新创建的数据库中。
答案 3 :(得分:12)
在PostgreSQL中,在添加字段时,它将添加到表的末尾。 如果我们需要插入特定位置,那么
alter table tablename rename to oldtable;
create table tablename (column defs go here);
insert into tablename (col1, col2, col3) select col1, col2, col3 from oldtable;
答案 4 :(得分:7)
答案 5 :(得分:5)
在PGAdmin中打开表,并在底部的SQL窗格中复制SQL Create Table语句。然后打开查询工具并粘贴。如果表有数据,请将表名更改为“new_name”,否则,删除“删除表”行中的注释“ - ”。根据需要编辑列序列。记住最后一栏中丢失/多余的逗号,以防你移动它。执行新的SQL Create Table命令。刷新并......瞧瞧。
对于设计阶段的空表,这种方法非常实用。
如果表有数据,我们也需要重新排列数据的列序列。这很简单:使用INSERT
将旧表导入其新版本:
INSERT INTO new ( c2, c3, c1 ) SELECT * from old;
...其中c2
,c3
,c1
是其中旧表格的c1
,c2
,c3
列新职位。请注意,在这种情况下,您必须为已编辑的“旧”表使用“新”名称,或您将丢失数据。如果列名称很多,则长和/或复杂使用与上面相同的方法将新表结构复制到文本编辑器中,并在将其复制到INSERT
语句之前创建新的列列表。 / p>
检查一切正常后,DROP
旧表格并使用ALTER TABLE new RENAME TO old;
将“新”名称更改为“旧”,您就完成了。
答案 6 :(得分:2)
我正在努力对许多表进行重新排序,并且不想一遍又一遍地编写相同的查询,因此我编写了一个脚本来为我完成所有这些工作。本质上,它是:
pg_dump
获取表创建SQL pg_dump
查询以创建包含数据的重新排序表可以通过运行以下简单命令来使用它:
./reorder.py -n schema -d database table \
first_col second_col ... penultimate_col ultimate_col --migrate
它会打印出sql,以便您可以验证和测试它,这是我基于pg_dump
建立它的重要原因。您可以找到github repo here。
答案 7 :(得分:0)
我使用Django,如果您不想头痛,它需要每个表中的id列。 不幸的是,我很粗心,我的表bp.geo_location_vague没有包含该字段。 我开始了一点小技巧。 步骤1:
CREATE VIEW bp.geo_location_vague_vw AS
SELECT
a.id, -- I change order of id column here.
a.in_date,
etc
FROM bp.geo_location_vague a
第2步:(不创建表-表将自动创建!)
SELECT * into bp.geo_location_vague_cp2 FROM bp.geo_location_vague_vw
第3步:
CREATE SEQUENCE bp.tbl_tbl_id_seq;
ALTER TABLE bp.geo_location_vague_cp2 ALTER COLUMN id SET DEFAULT nextval('tbl_tbl_id_seq');
ALTER SEQUENCE bp.tbl_tbl_id_seq OWNED BY bp.geo_location_vague_cp2.id;
SELECT setval('tbl_tbl_id_seq', COALESCE(max(id), 0)) FROM bp.geo_location_vague_cp2;
因为我需要在表中使用bigserial伪类型。将SELECT *转换为pg后,将创建bigint类型的insetad bigserial。
步骤4: 现在我们可以删除视图,删除源表,并以旧名称重命名新表。 trick俩成功结束了。
答案 8 :(得分:0)
有一些变通办法可以实现:
重新创建整个表
在当前表中创建新列
创建视图