18

我在 PostgreSQL 数据库中有一个大型查询。查询是这样的:

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

当我将此查询作为 sql 查询运行时,它会返回所需的行。

但是当我尝试使用相同的查询来创建视图时,它会返回一个错误:

“错误:列“id”指定了多次。”

(我在执行查询时使用 pgAdminIII。)

我猜会发生这种情况,因为结果集将有多个名为“id”的列。有没有办法解决这个问题,而无需在查询中写入所有列名?

4

4 回答 4

20

发生这种情况是因为视图将有两个 id 命名的列,一个来自 table1,一个来自 table2,因为 select *.

您需要在视图中指定您想要的 id。

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
于 2008-10-16T10:02:59.073 回答
17

如果只有连接列是重复的(即具有相同的名称),那么您可以摆脱更改:

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

到:

select *
from a join b using (id)
于 2009-09-29T17:25:49.803 回答
0

如果您来到这里是因为您尝试使用类似的函数to_date并收到“多次定义”错误,请注意您需要为函数使用列别名,例如:

to_date(o.publication_date, 'DD/MM/YYYY') AS publication_date
于 2017-08-15T03:08:06.577 回答
-2

语言中没有内置的方法来解决它(坦率地说,* 通常是一种不好的做法,因为它可能会导致潜在缺陷随着表模式的变化而出现 - 你可以做 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
于 2008-10-16T13:59:09.003 回答