Pergunta

Eu tenho uma grande consulta em um banco de dados PostgreSQL. A consulta é algo como isto:

SELECT * FROM table1, table2, ... WHERE table1.id = table2.id...

Quando eu executar essa consulta como uma consulta SQL, o que retorna a linha queria.

Mas quando eu tenta usar a mesma consulta para criar uma visão, ele retorna um erro:

"erro: coluna "id". Especificado mais de uma vez"

(eu uso pgAdminIII ao executar as consultas.)

Eu acho que isso acontece porque o conjunto de resultados terá mais de uma coluna chamada "id". Existe alguma maneira de resolver isso, sem escrever todos os nomes das colunas na consulta?

Foi útil?

Solução

Isso acontece porque uma visão teria duas colunas id chamado, um de table1 e um da table2, por causa da escolha *.

Você precisa especificar quais id você quer na vista.

SELECT table1.id, column2, column3, ... FROM table1, table2 
WHERE table1.id = table2.id

A consulta funciona porque pode ter igualmente chamado colunas ...

postgres=# select 1 as a, 2 as a;
 a | a
---+---
 1 | 2
(1 row)

postgres=# create view foobar as select 1 as a, 2 as a;
ERROR:  column "a" duplicated
postgres=# create view foobar as select 1 as a, 2 as b;
CREATE VIEW

Outras dicas

Se apenas se juntar colunas são duplicados (ou seja, têm os mesmos nomes), então você pode ir longe com a mudança:

select *
from a, b
where a.id = b.id

para:

select *
from a join b using (id)

Se você chegou aqui porque você está tentando usar uma função como to_date e recebendo o "definido mais de uma vez" Erro, nota que você precisa usar um alias de coluna para as funções, por exemplo:.

to_date(o.publication_date, 'DD/MM/YYYY') AS publication_date

No built-in maneira na língua de resolvê-lo (e, francamente, * é uma má prática em geral, pois pode causar defeitos latentes de surgir como alterar a tabela esquemas -. Você pode fazer table1 *, table2.acolumn, tabl2.bcolumn se você quiser todos de uma só mesa e selectiva de outro), mas se PostgreSQL suporta INFORMATION_SCHEMA, você pode fazer algo como:

DECLARE @sql AS varchar

SELECT @sql = COALESCE(@sql + ', ', '') 
    + '[' + TABLE_NAME + '].[' + COLUMN_NAME + ']'
    + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN ('table1', 'table2')
ORDER BY TABLE_NAME, ORDINAL_POSITION

PRINT @sql

E colar os resultados em para salvar um monte de digitação. Você terá que manualmente apelido as colunas que têm o mesmo nome, é claro. Você também pode código-gen nomes exclusivos se você gosta (mas eu não):

SELECT @sql = COALESCE(@sql + ', ', '') 
    + '[' + TABLE_NAME + '].[' + COLUMN_NAME + '] '
    + 'AS [' + TABLE_NAME + '_' + COLUMN_NAME + ']'
    + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN ('table1', 'table2')
ORDER BY TABLE_NAME, ORDINAL_POSITION
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top