使用 CTE 为主查询选择列

Posted

技术标签:

【中文标题】使用 CTE 为主查询选择列【英文标题】:Using CTE to pick columns for main query 【发布时间】:2021-03-27 17:12:20 【问题描述】:

可重现的示例

这利用了 bigquery 公共数据集,但可以随意替换类似的数据结构:

with common_columns as (
    select c1.column_name from `bigquery-public-data`.ml_datasets.INFORMATION_SCHEMA.COLUMNS c1 where c1.table_name = 'iris'
    INTERSECT DISTINCT
    select c2.column_name from `bigquery-public-data`.ml_datasets.INFORMATION_SCHEMA.COLUMNS c2 where c2.table_name = 'iris' and not regexp_contains(c2.column_name,r'sepal')
)

select `species`,`petal_width`,`petal_length` from `bigquery-public-data`.ml_datasets.iris
UNION ALL 
select `species`,`petal_width`,`petal_length` from `bigquery-public-data`.ml_datasets.iris

目标

我想要完成的是使用 CTE 找到 c1c2 之间的公共列,然后在联合查询中引用这些公共表。

类似:

select (insert column_names from common_columns here) from my_dataset
UNION ALL
select (insert column_names from common_columns here) from my_second_dataset

(为了这个示例,我将 c1c2 视为完全不同的表,只是为了一个简单的示例而使用相同的源表)

【问题讨论】:

【参考方案1】:

考虑下面的例子

execute immediate( 
  select * from (
    with common_columns as (
      select c1.column_name from `bigquery-public-data`.ml_datasets.INFORMATION_SCHEMA.COLUMNS c1 where c1.table_name = 'iris'
      INTERSECT DISTINCT
      select c2.column_name from `bigquery-public-data`.ml_datasets.INFORMATION_SCHEMA.COLUMNS c2 where c2.table_name = 'iris' and not regexp_contains(c2.column_name,r'sepal')
    )
    select 'select ' || string_agg(column_name, ', ') || ' from `bigquery-public-data`.ml_datasets.iris'
    from common_columns
  )
)      

正如您在此处看到的 - 内部选择

with common_columns as (
    select c1.column_name from `bigquery-public-data`.ml_datasets.INFORMATION_SCHEMA.COLUMNS c1 where c1.table_name = 'iris'
    INTERSECT DISTINCT
    select c2.column_name from `bigquery-public-data`.ml_datasets.INFORMATION_SCHEMA.COLUMNS c2 where c2.table_name = 'iris' and not regexp_contains(c2.column_name,r'sepal')
)
select 'select ' || string_agg(column_name, ', ') || ' from `bigquery-public-data`.ml_datasets.iris'
from common_columns    

输出动态构建最终选择语句 - 输出是

... 然后 - execute immediate 执行它。显然,您可以修改该内部查询以构建您的情况所需的任何内容 - 包括联合所有等。

【讨论】:

我不知道 execute immediate 的存在。谢谢!

以上是关于使用 CTE 为主查询选择列的主要内容,如果未能解决你的问题,请参考以下文章

无法计算 CTE 子查询输出之间的差异以用于更大的 PostgreSQL 查询输出列

查询性能:CTE 使用 ROW_NUMBER() 选择第一行

调整查询以使用 CTE

如何在不使用 join 或 cte 的情况下在同一查询中使用动态生成的列

在 CTE 中对日期范围内的列求和?

PostgREST 在子查询或 CTE 中使用限制和偏移量