Visualizza errore in PostgreSQL
-
03-07-2019 - |
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?
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