【发布时间】:2012-03-23 15:06:09
【问题描述】:
我正在寻找一种方法来获取特定表中每一列的计数。应从 information_schema.columns 中查询列名。结果应如下所示:
column_name : count
我可以用 sql 查询这个还是我需要一个我从未做过的函数。
感谢您的帮助。 草地
【问题讨论】:
-
我们需要您的 PostgrreSQL 版本
标签: postgresql count rows
我正在寻找一种方法来获取特定表中每一列的计数。应从 information_schema.columns 中查询列名。结果应如下所示:
column_name : count
我可以用 sql 查询这个还是我需要一个我从未做过的函数。
感谢您的帮助。 草地
【问题讨论】:
标签: postgresql count rows
此查询将创建 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
...
【讨论】:
mytbl?
我想要这个问题的动态解决方案,所以,使用@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$
;
【讨论】: