我在 PostgreSQL 数据库中有一个大型查询。 查询是这样的:
SELECT * FROM table1, table2, ... WHERE table1.id = table2.id...
当我将此查询作为 sql 查询运行时,它返回所需的行。
但是当我尝试使用相同的查询来创建视图时,它返回一个错误:
“错误:多次指定列“id”。”
(我在执行查询时使用 pgAdminIII。)
我猜会发生这种情况,因为结果集将有多个名为“id”的列。有没有办法解决这个问题,而不用在查询中写下所有列名?
发生这种情况是因为视图有两个 id 命名列,一个来自 table1,一个来自 table2,因为选择 *.
你需要在视图中指定你想要的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
如果只有连接列是重复的(即具有相同的名称),那么您可以更改:
select *
from a, b
where a.id = b.id
至:
select *
from a join b using (id)
对我来说,这是由于我大量添加列。 之前版本的create view语句有5列。 我在最终选择中添加了 3 个新列,但在创建视图语句开头的列列表中仅添加了 2 个。 修复列列表后,问题就消失了。 至于我,错误消息没有帮助。
如果你来到这里是因为你正在尝试使用像
to_date
这样的函数并得到“多次定义”错误,请注意你需要为函数使用列别名,例如:
to_date(o.publication_date, 'DD/MM/YYYY') AS publication_date
语言中没有内置的方法来解决它(坦率地说,* 通常是一种不好的做法,因为它会导致潜在的缺陷随着表模式的变化而出现——你可以做 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