postgresql 错误:多次指定列“id”-创建视图时[重复]

ccrfmcuu  于 2023-04-11  发布在  PostgreSQL
关注(0)|答案(2)|浏览(372)

此问题已在此处有答案

View error in PostgreSQL(4个答案)
4天前关闭。
我写了这段代码,它可以工作:

SELECT d1.*,d3.*
FROM bdir_programmation.d_program AS d1 
JOIN (
    SELECT d_program.id,MAX(id_reg) AS maxv
    FROM bdir_programmation.d_program
    GROUP BY d_program.id) AS d2 ON d1.id=d2.id AND d1.id_reg=d2.maxv
JOIN bdir_programmation.d_infra_progra d3 ON d1.id=d3.id;

但是当我想创建一个视图时,我得到了这个错误:
错误:多次指定列“id”
我尝试重命名SELECT列表中的不同变量,如其他主题所述,但在这种情况下,它似乎没有以正确的方式进行。我对结构有一些困难,这对我来说是全新的。

zxlwwiss

zxlwwiss1#

d_programd_infra_progra都有一个名为id的列。这适用于查询,其中两个列可以具有相同的别名,但不适用于视图,其中列名必须是唯一的。
由于两列的值相同,因此只取其中一列。这需要您取消*,并枚举您需要的列,如果您愿意,可以为它们提供别名。

xwbd5t1u

xwbd5t1u2#

视图不能生成具有重复列名的派生表,如Laurenz所述。
您可以在join中使用USING子句来简化查询,以吞下重复的(相同的,因此无论如何都是噪声)列。

SELECT *
FROM   bdir_programmation.d_program d1 
JOIN  (
    SELECT d.id, MAX(d.id_reg) AS id_reg  -- instead of maxv
    FROM   bdir_programmation.d_program d
    GROUP  BY 1
    ) d2 USING (id, id_reg)
JOIN   bdir_programmation.d_infra_progra d3 USING (id);

除非有更多相同的名字。
参见:

  • 如何在连接两个表时删除一个连接键

但是,通常情况下,使用DISTINCT ON会更简单、更便宜:

SELECT *
FROM  (
   SELECT DISTINCT ON (id) *
   FROM   bdir_programmation.d_program AS d1 
   ORDER  BY d.id_reg DESC NULLS LAST
   ) d1
JOIN   bdir_programmation.d_infra_progra d3 USING (id);

参见:

  • 是否选择每个GROUP BY组中的第一行?

排序顺序DESC NULLS LAST产生max()的等价物。参见:

  • 优化groupwise最大查询

同样,USING子句吞下id列的第二个相同示例。
无论哪种方式,视图定义都将SELECT *转换为在创建时由查询生成的列的迭代列表(“早期绑定”)。

相关问题