2008-10-16 7 views
9

Ich habe eine große Abfrage in einer PostgreSQL-Datenbank. Die Abfrage ist so etwas wie folgt aus:Fehler in PostgreSQL anzeigen

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

Wenn ich diese Abfrage als SQL-Abfrage ausführen, die es die gewünschte Zeile zurückgibt.

Aber wenn ich die gleiche Abfrage zu verwenden versucht, eine Ansicht zu erstellen, gibt es eine Fehlermeldung:

„Fehler: Spalte‚‘mehr als einmal angegeben“ id

(ich verwende pgAdminIII, wenn die Ausführung von Abfragen.)

Ich denke, dies geschieht, weil das Suchresultates wird mehr als eine Spalte „id“ genannt hat. Gibt es eine Möglichkeit, dies zu lösen, ohne alle Spaltennamen in der Abfrage zu schreiben?

Antwort

11

Das passiert, weil eine Ansicht zwei id-benannte Spalten haben würde, eine aus Tabelle1 und eine aus Tabelle2, wegen der Auswahl *.

Sie müssen angeben, welche ID in der Ansicht angezeigt werden soll.

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

Die Abfrage funktioniert, weil es gleichermaßen Spalten genannt haben können ...

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 
+3

Gibt es eine Möglichkeit, Tabellennamen den Spaltennamen im Ergebnis einer SELECT * -Abfrage automatisch voran zu stellen? – nnyby

-2

Keine integrierte Möglichkeit, in der Sprache, es zu lösen (und ehrlich gesagt, * ist eine schlechte Praxis in der Regel, weil Es kann zu latenten Fehlern kommen, wenn sich die Tabellenschemas ändern - Sie können table1. *, table2.acolumn, tabl2.bcolumn tun, wenn Sie alle Tabellen und selektiv von einem anderen verwenden möchten. Wenn PostgreSQL jedoch INFORMATION_SCHEMA unterstützt, können Sie etwas tun wie:

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 

Und fügen Sie die Ergebnisse ein, um viel Tipparbeit zu sparen. Sie müssen die Spalten natürlich umbenennen, die den gleichen Namen haben. Sie können auch Code-gen eindeutige Namen, wenn Sie mögen (aber ich weiß nicht):

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 
+0

Es gibt nichts wie @SOMETHING in PostgreSQL. –

+0

Es gibt auch keine Verwendung von [], um Bezeichner zu zitieren. Und nicht CHAR() -Funktion. Und keine PRINT-Anweisung. –

11

Wenn nur Joinspalten dupliziert werden (dh die gleichen Namen), dann können Sie weg mit Wechsel:

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

zu:

select * 
from a join b using (id) 
+0

Das behebt den Fehler nicht, aber es ist sowieso eine schönere Syntax. –

0

Wenn Sie hier, weil Sie eine Funktion wie to_date und bekommen die „definiert, die mehr als einmal“ zu verwenden versuchen Fehler, beachten Sie, dass Sie eine Spalte Alias ​​für Funktionen verwenden müssen zB:

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