Domanda

Ho una query di grandi dimensioni in un database PostgreSQL. La query è qualcosa del genere:

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

Quando eseguo questa query come query sql, restituisce la riga desiderata.

Ma quando provo a utilizzare la stessa query per creare una vista, viene restituito un errore:

" errore: colonna " id " specificato più di una volta. "

(Uso pgAdminIII durante l'esecuzione delle query.)

Immagino che ciò accada perché il set di risultati avrà più di una colonna denominata " id " ;. C'è un modo per risolverlo, senza scrivere tutti i nomi delle colonne nella query?

È stato utile?

Soluzione

Ciò accade perché una vista avrebbe due colonne denominate id, una dalla tabella1 e una dalla tabella2, a causa della selezione *.

Devi specificare quale ID vuoi nella vista.

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

La query funziona perché può avere colonne ugualmente denominate ...

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

Altri suggerimenti

Se vengono duplicate solo le colonne di join (ovvero hanno gli stessi nomi), puoi evitare di cambiare:

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

a:

select *
from a join b using (id)

Se sei arrivato qui perché stai provando a utilizzare una funzione come to_date e stai ottenendo il "quot" più di una volta " errore, si noti che è necessario utilizzare un alias di colonna per le funzioni, ad esempio:

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

Nessun modo integrato nel linguaggio per risolverlo (e francamente, * è una cattiva pratica in generale perché può causare l'insorgere di difetti latenti quando cambiano gli schemi delle tabelle - puoi fare table1. *, table2.acolumn, tabl2.bcolumn se vuoi tutta una tabella e selettivamente da un'altra), ma se PostgreSQL supporta INFORMATION_SCHEMA, puoi fare qualcosa del tipo:

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 incolla i risultati per risparmiare molta digitazione. Ovviamente dovrai aliasare manualmente le colonne che hanno lo stesso nome. Puoi anche codificare nomi univoci se ti piace (ma io no):

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top