Просмотреть ошибку в PostgreSQL - PullRequest
12 голосов
/ 16 октября 2008

У меня большой запрос в базе данных PostgreSQL. Запрос выглядит примерно так:

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

Когда я запускаю этот запрос как SQL-запрос, он возвращает искомую строку.

Но когда я пытаюсь использовать тот же запрос для создания представления, он возвращает ошибку:

"ошибка: столбец" id "указан более одного раза."

(я использую pgAdminIII при выполнении запросов.)

Полагаю, это происходит потому, что в наборе результатов будет более одного столбца с именем "id". Есть ли способ решить эту проблему, не записывая все имена столбцов в запросе?

Ответы [ 4 ]

14 голосов
/ 16 октября 2008

Это происходит потому, что у представления будет два столбца с именами, один из таблицы1 и один из таблицы2, из-за выбора *.

Вам необходимо указать, какой идентификатор вы хотите видеть.

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

Запрос работает, потому что он может иметь столбцы с одинаковыми именами ...

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
13 голосов
/ 29 сентября 2009

Если дублируются только объединяемые столбцы (т. Е. Имеют одинаковые имена), то вы можете избежать изменения:

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

до:

select *
from a join b using (id)
0 голосов
/ 15 августа 2017

Если вы попали сюда из-за того, что пытаетесь использовать функцию, подобную to_date, и получаете ошибку «определено более одного раза», обратите внимание, что вам необходимо использовать псевдоним столбца для функций, например ::

to_date(o.publication_date, 'DD/MM/YYYY') AS publication_date
0 голосов
/ 16 октября 2008

Нет встроенного в язык способа ее решения (и, честно говоря, * это вообще плохая практика, потому что это может привести к возникновению скрытых дефектов при изменении схем таблиц - вы можете сделать table1. *, Table2.acolumn, tabl2.bcolumn, если вам нужна вся одна таблица и выборочно из другой), но если PostgreSQL поддерживает INFORMATION_SCHEMA, вы можете сделать что-то вроде:

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

И вставьте результаты, чтобы сэкономить много печатать. Конечно, вам нужно будет вручную создать псевдоним столбцов с одинаковыми именами. Вы также можете кодировать уникальные имена, если хотите (но мне не нравится):

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
...