Como posso especificar a posição para uma nova coluna no PostgreSQL?

74

Se eu tiver uma tabela com as colunas:

id | name | created_date

e gostaria de adicionar uma coluna, eu uso:

alter table my_table add column email varchar(255)

Em seguida, a coluna é adicionada após a created_datecoluna.

Existe alguma maneira de especificar a posição da nova coluna? por exemplo, para que eu possa adicioná-lo depois namee obter uma tabela como:

id | name | email | created_date
Jonas
fonte
4
Não há necessidade de fazer isso. Basta colocá-los em sua instrução select na ordem em que você os desejar.
a_horse_with_no_name 12/06
@jonas para que você também possa criar um viewprograma que mostre nessa ordem ... tecnicamente a posição da coluna não deve importar, pois você pode defini-los em qualquer ordem em uma consulta ... e geralmente não deve fazer umselect *
Xenoterracide
2
@a_horse: Bem, é muito mais difícil trabalhar (como desenvolvedor / administrador) com as tabelas quando as colunas têm muitos pedidos diferentes. Quando tenho 15 colunas em uma tabela, prefiro tê-las na mesma ordem em todos os bancos de dados.
Jonas
2
@jonas, você pode definir os nomes das colunas ao fazer inserções e atualizações e, assim, tornar o pedido irrelevante.
Xenoterracide
2
@ Jonas: Em seguida, escreva a sua própria alternativa para \ d que relata as colunas na ordem que você quiser (é apenas uma consulta nas tabelas do sistema: tente usar o psql -Einterruptor para ver a consulta real)
Jack Douglas

Respostas:

54

ALTER TABLE ADD COLUMNadicionará apenas a nova coluna no final, como a última. Para criar uma nova coluna em outra posição, é necessário recriar a tabela e copiar os dados da tabela antiga / atual nesta nova tabela.

Marian
fonte
4
É isso mesmo .. mas alguém realmente usa esse método? :-)
Marian
2
Se for mais fácil do que recriar a tabela e todas as tabelas filho , chaves estrangeiras e concessões :) Eu pensei que o link poderia ser útil de qualquer maneira, pois oferece uma explicação de por que você não pode especificar a posição e espero que possa ser implementado em um versão futura.
Jack Douglas
22

Você precisará recriar a tabela se desejar uma determinada ordem. Basta fazer algo como:

alter table tablename rename to oldtable;
create table tablename (column defs go here);
insert into tablename (col1, col2, col3) select col2, col1, col3 from oldtable;

Crie índices conforme necessário etc.

Scott Marlowe
fonte
2

Se você quer isso apenas para a aparência, acho mais fácil manter uma visualização para cada tabela com a ordem desejada das colunas e selecioná-la em vez da tabela.

create table my_table (
create view view_my_table as
  select id, name, created_date from my_table;

-- adding a new column
begin;
alter table my_table add column email varchar(255);
drop view view_my_table;
create view view_my_table as
  select id, name, email, created_date from my_table;
commit;

Para todos os outros fins (como inserção, união), é melhor sempre especificar a lista de colunas.

-- bad
insert into my_table values (...);
(select * from my_table)
  union all
(select * from my_table);

-- good
insert into my_table (id, name, email, created_date) values (...);
(select id, name, email, created_date from my_table)
  union all
(select id, name, email, created_date from my_table);
Simon Perepelitsa
fonte