【问题标题】:postgresql - count (no null values) of each column in a tablepostgresql - 表中每列的计数(无空值)
【发布时间】:2012-03-23 15:06:09
【问题描述】:

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

column_name : count

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

感谢您的帮助。 草地

【问题讨论】:

  • 我们需要您的 PostgrreSQL 版本

标签: postgresql count rows


【解决方案1】:

此查询将创建 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 的更多信息。

顺便说一句:NULL 值默认不会添加到 COUNT(col)

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

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

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

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

【讨论】:

  • 感谢您的回答。但是当我执行它时,我得到一个空结果。
  • @user1288241:对我有用,我在发布前进行了测试。你知道你需要用你的(模式限定,如果需要的话)表名替换mytbl?
  • 是的,我做到了。我有一个 postgresql 9.1,表有大约 600 列。该表如下所示: CREATE TABLE geoproject.mes_wastab ( invid 字符变化 (16), invtype 字符变化 (3), smpid 整数, smpname 字符变化 (40), smpdate 日期, smptime 字符变化 (5), o2st_p 双精度, wspgokna 双精度,o2_p 双精度,absenkungs 双精度,klarstrom3 双精度,klarstrom2 双精度,klarstrom4 双精度,............ ..... ) WITH ( OIDS=FALSE );有什么想法吗?
  • @user1288241:建议您在问题中编辑大量信息。这也更容易阅读。只需点击问题下方的“编辑”即可。
【解决方案2】:

我想要这个问题的动态解决方案,所以,使用@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$
;

【讨论】:

    猜你喜欢
    • 2021-11-25
    • 2011-11-05
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    相关资源
    最近更新 更多