postgresql - 表中每列的count(无空值)

时间:2012-03-23 15:06:09

标签: postgresql count rows

我正在寻找一种方法来获取特定表中每列的计数。应该从information_schema.columns查询列名。结果应如下所示:

column_name : count

我可以用sql查询,还是需要一个我从未做过的函数。

感谢您的帮助。 grassu

2 个答案:

答案 0 :(得分:2)

此查询将创建DML语句以获得所需内容。

SELECT 'SELECT ' || string_agg('count(' || quote_ident(attname) || ')', ', ')
    || 'FROM '   || attrelid::regclass
FROM   pg_attribute
WHERE  attrelid = 'mytbl'::regclass
AND    attnum  >= 1           -- exclude tableoid & friends (neg. attnum)
AND    attisdropped is FALSE  -- exclude deleted columns
GROUP  BY attrelid;

返回:

SELECT count(col1), count(col2), count(col3), ...
FROM   mytbl

您也可以自动执行它。但是在计划SQL中,在plpgsql函数或DO语句(PostgreSQL 9.0或更高版本)中需要EXECUTE

string_agg()功能还需要Postgres 9.0或更高版本。在旧版本中,您可以替换:array_to_string(array_agg(...), ', ')

您可能想知道特殊演员'mytbl'::regclass。请阅读手册中有关object identifier types的更多信息。

BTW:默认情况下,NULL值不会添加到COUNT(col)

替换mytbl的(模式限定的)表名。在您的情况下应该是:

...
WHERE  attrelid = 'geoproject.mes_wastab'::regclass
...

如果您应该使用混合大小写或其他搞乱的标识符(请注意引号):

...
WHERE  attrelid = '"gEopRoject"."MES_wastab"'::regclass
...

答案 1 :(得分:0)

我想要一个动态解决此问题的方法,因此,使用@Erwin提出的查询,这是一个仅需要表和架构名称并输出如下表的函数:

columns, percentage
------------------
colname1, perc1
colname2, perc2
...
colnamen, percn
CREATE OR REPLACE FUNCTION public.completeness_histogram(_tabella text, _schema text)
 RETURNS TABLE(columns text, percentage numeric)
 LANGUAGE plpgsql
AS $function$
declare 
    seed_query text;
    col_list text;
    intermediate_query text;
    final_query text;
begin

    SELECT 'SELECT ' || string_agg(concat('round(100 * count(', col
                      , ') / count(*)::numeric, 2) AS ', col_pct), E'\n     , ')
        || E'\nFROM   ' ||  tbl into seed_query
    FROM (
       SELECT quote_ident(table_schema) || '.' || quote_ident(table_name) AS tbl
            , quote_ident(column_name) AS col
            , quote_ident(column_name) AS col_pct
       FROM   information_schema.columns
       WHERE  table_name = _tabella
       and    table_schema = _schema
       ORDER  BY ordinal_position
       ) sub
    GROUP  BY tbl;

    select string_agg(col_pct, ', ') into col_list
    from (
       SELECT quote_ident(column_name) AS col_pct
       FROM   information_schema.columns
       WHERE  table_name = _tabella
       and table_schema = _schema
       ORDER  BY ordinal_position
    ) foo;

    
    intermediate_query := format('SELECT ''SELECT * FROM unnest(
      ''''{%s}''''::text[]
    , '' || string_agg(quote_literal(ARRAY[%s])
                  || ''::numeric[]'', E''\n, '')
        || E'') \n AS t(col, completezza)'' AS sql
    FROM   (
        %s
    ) foo;', col_list, col_list, seed_query);

    execute format(intermediate_query)  into final_query;

    return query execute format(final_query);
    
end;
$function$
;