【问题标题】:View error in PostgreSQL在 PostgreSQL 中查看错误
【发布时间】:2010-09-17 12:03:44
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

    标签: sql postgresql pgadmin


    【解决方案1】:

    发生这种情况是因为视图将有两个 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
    

    【讨论】:

    • 有没有办法在 SELECT * 查询的结果中自动将表名添加到列名中?
    【解决方案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
    

    【讨论】:

    • PostgreSQL 中没有像@SOMETHING 这样的东西。
    • 也没有使用 [] 来引用标识符。而不是 CHAR() 函数。并且没有 PRINT 声明。
    【解决方案3】:

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

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

    到:

    select *
    from a join b using (id)
    

    【讨论】:

    • 这并没有修复错误,但无论如何它是一个更好的语法。
    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 2018-12-06
      • 2014-07-08
      • 1970-01-01
      • 2012-02-05
      相关资源
      最近更新 更多