重复的列名称在Postgres视图中合并

时间:2019-06-19 17:03:47

标签: sql postgresql view

在我们的数据库中,我们有一个视图,其中包含诸如SELECT *, lower(mix_cased_field) AS mix_cased_field之类的子选择,其中*已经包含名为mix_cased_field的列。

我的期望是冲突的列(即mix_cased_field)将被合并,而后者将继续存在,即在我的最终结果集中只有小写的字段。

实际结果是,在我的结果集中,我有两个字段; mix_cased_fieldmix_cased_field_1。当我查看pg_views表中的视图定义时,我发现后一个字段已由Postgres重命名为后缀,尽管我对该列进行了明确的命名。

对该视图的查询大致如下:

-- (table and column names have been renamed to protect the innocent)

SELECT 
  *,
  'TopmostThing' AS __type,
  (
    SELECT COALESCE(jsonb_agg(sub_things), '[]'::jsonb) AS sub_things
    FROM (
      SELECT 
        *,
        'SubThing' AS __type,
        json_date(created_at) AS created_at,
        lower(mix_cased_field) AS mix_cased_field,
        (
          SELECT COALESCE(jsonb_agg(yet_more_things), '[]'::jsonb) AS yet_more_things
          FROM (
            SELECT
              *,
              'YetMoreThing' AS __type,
              lower(mix_cased_field) AS mix_cased_field
            FROM yet_more_things
            WHERE yet_more_things.subthing_id = subthings.id
          ) AS yet_more_things
        )
      FROM sub_things
      WHERE sub_things.topmost_thing_id = topmost_things.id
    ) AS sub_things
  )
FROM topmost_things

当我运行用于构造视图的查询时,结果集符合我的期望。这是预期的行为,我一无所知,还是一个错误?

1 个答案:

答案 0 :(得分:1)

原因很简单:允许SELECT返回多个具有相同名称的列(即使某些客户端不允许相同)。但是CREATE VIEW不允许这样做,因为表(和视图)根本不允许重复的列名。

但此案的预期行为是:

ERROR:  column "mix_case_column" specified more than once

在Postgres 11中测试。

Postgres不会自动重命名类似的列。至少据我所知。可能存在一些中间件干扰吗?