使用 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 找到 c1
和 c2
之间的公共列,然后在联合查询中引用这些公共表。
类似:
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
(为了这个示例,我将 c1
和 c2
视为完全不同的表,只是为了一个简单的示例而使用相同的源表)
【问题讨论】:
【参考方案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() 选择第一行