小编典典

排除联接中的重复字段

sql

我有一个要分析的数据集。事实证明,可以轻松地通过人口统计和社区数据来充实其内容,从而极大地改善了分析结果。

为此,在进行分析之前,我将加入人口统计数据和社区数据。我需要从核心样本集中排除一些字段,所以我的联接看起来像这样:

select sampledata.c1, 
       sampledata.c2, 
       demographics.*, 
       community.* 
from sample data 
    join demographics using (zip) 
    join community using (fips)

这使我的分析引擎无法处理输出中的多个zip或fips列。我无法手动指定每个字段-充实表最终导致数百列。

我可以选择*,但是我会从样本数据中得到所有不需要的列。

如何在不重复字段的情况下加入我的浓缩数据,同时仍从样本表中选择所需的列?

我曾经想过,如果postgres(我的数据库)可以完全限定输出中的每一列(例如sample.c1,demographics.c1等),我将对此感到非常满意。


阅读 170

收藏
2021-05-23

共1个答案

小编典典

SQL中没有列排除语法,只有列包含语法(通过所有列的*运算符,或显式列出列名称)。

生成所需的仅列列表

但是,您可以使用架构表和数据库的某些内置函数来生成带有数百个列名的SQL语句,然后减去不需要的几个重复列。

SELECT
    'SELECT sampledata.c1, sampledata.c2, ' || ARRAY_TO_STRING(ARRAY(
        SELECT 'demographics' || '.' || column_name
        FROM information_schema.columns
        WHERE table_name = 'demographics' 
        AND column_name NOT IN ('zip')
        UNION ALL
        SELECT 'community' || '.' || column_name
        FROM information_schema.columns
        WHERE table_name = 'community' 
        AND column_name NOT IN ('fips')
    ), ',') || ' FROM sampledata JOIN demographics USING (zip) JOIN community USING (fips)'
AS statement

这只会打印出该语句,不会执行它。然后,您只需复制结果并运行即可。

如果您想一次性动态生成和运行语句,则可以在PostgreSQL文档中阅读如何运行动态SQL 。

在列名前加上表名

或者,这将生成所有列的选择列表,包括具有重复数据的那些列,但随后为它们添加别名以包括每个列的表名。

SELECT
    'SELECT ' || ARRAY_TO_STRING(ARRAY(
        SELECT table_name || '.' || column_name || ' AS ' || table_name || '_' || column_name
        FROM information_schema.columns
        WHERE table_name in ('sampledata', 'demographics', 'community')
    ), ',') || ' FROM sampledata JOIN demographics USING (zip) JOIN community USING (fips)'
AS statement

同样,这仅生成语句。如果要同时动态生成和运行语句,则需要重新启动数据库的动态SQL执行,否则只需复制并运行结果即可。

如果您确实希望在列别名中使用点分隔符,则必须使用双引号别名,例如SELECT table_name || '.' || column_name || ' AS "' || table_name || '.' || column_name || '"'。但是,双引号别名会导致额外的复杂性(区分大小写等);因此,我改用下划线字符将表名与别名中的列名分开,然后可以将别名与常规列名一样对待。

2021-05-23