代码之家  ›  专栏  ›  技术社区  ›  l0b0

如何仅选择具有多个值的*列*?

  •  0
  • l0b0  · 技术社区  · 4 年前

    SELECT DISTINCT … 删除重复行。有没有办法删除重复项 柱, 也就是说,每个值都相同的列?我正在查看一些行的“区别特征”的遗留模式,所以这将非常有帮助。如果这让它更容易,那么所有列都是简单的类型,比如 INT , TEXT TIMESTAMP .基本上,给定这样一个表:

    CREATE TEMPORARY TABLE column_test
    (
        foo TEXT,
        bar INT,
        baz BOOLEAN,
        bat TIMESTAMP WITH TIME ZONE
    );
    
    INSERT INTO column_test (
        foo, bar, baz, bat
    ) VALUES
        ('lorem ipsum', 1, TRUE, '2000-01-01 UTC'),
        ('lorem ipsum', 2, TRUE, '2000-01-01 UTC'),
        ('other', 3, TRUE, '2000-01-01 UTC');
    

    是否可以编写一个只选择 foo bar 列,因为这些是唯一具有多个值的列?大致如下:

    SELECT columns_with_more_than_one_value(*) FROM column_test;
    foo           bar
    'lorem ipsum' 1
    'lorem ipsum' 2
    'other'       3
    

    我想一个办法是 SELECT * ,转置结果,删除所有值都相同的行,然后再次转置,但这将非常复杂,我不知道如何在结果中保留原始列名。

    0 回复  |  直到 4 年前
        1
  •  1
  •   klin    4 年前

    基本上,您不能从表中选择未知列。查询结果在执行之前必须定义一个结构。您可以做的是创建一个包含预期列的(临时)视图。下面的函数可以完成这项工作,广泛使用 dynamic SQL. 该函数的第一个参数是表名,第二个参数是要创建的临时视图的名称。

    create or replace function create_view_with_distinct_columns(text, text)
    returns void language plpgsql as $$
    declare
        col text;
        ct int;
        list text = '';
    begin
        for col in 
            execute format('
                select attname
                from pg_attribute
                where attrelid = %s
                and attnum > 0',
                $1::regclass::oid)
        loop
            execute format('
                select count(distinct %I)
                from %I',
                col, $1)
            into ct;
            if ct > 1 then
                list:= format('%s%s,', list, col);
            end if;
        end loop;
        execute format('
            create temp view %I as
            select %s
            from %I',
            $2, left(list, -1), $1);
    end $$;
    

    用途:

    select create_view_with_distinct_columns('column_test', 'column_view');
    
    select * from column_view;
    
         foo     | bar
    -------------+-----
     lorem ipsum |   1
     lorem ipsum |   2
     other       |   3
    (3 rows)    
    

    Db<>fiddle.

    推荐文章