表中每列的计数(非空)PostgreSQL PL/pgSQL

nlejzf6q  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(368)

我尝试计算表中每列不包含空值的行数
有一个简单的表actor_new前2列(actor_id、first_name)包含203行非空值,其他2列(last_name、last_update)包含200行非空值
这是一个为所有列输出相同值的简单测试,但如果您单独执行select,则一切都正常工作,请帮助我理解LOOP块

create or replace function new_cnt_test_ho(in_table text, out out_table text, out cnt_rows int) returns setof record AS $$ 
DECLARE i text;
BEGIN 
    FOR i IN 
        select column_name 
        from information_schema."columns" 
        where table_schema = 'public' 
        and table_name = in_table
    LOOP 
        execute '
        select $1, count($1)
        from '|| quote_ident(in_table) ||'
        where $1 is not null '
        INTO out_table, cnt_rows
        using i, quote_literal(i), quote_ident(in_table), quote_literal(in_table) ;
        return next;
    END LOOP;
END;
$$LANGUAGE plpgsql

结果:
第一次

using中指定了4个参数,因为我假定错误在引号中,所以我轮流使用参数1到4
正确的结果应该是这样的

out_table  |cnt_rows|
-----------+--------+
actor_id   |     203|
first_name |     203|
last_name  |     200|
last_update|     200|
3phpmpom

3phpmpom1#

根据您的职位:输入是表名,输出是表,其中一列是列名,另一列是返回的计数(列)
首先检查表是否存在。然后for循环得到每个列名,然后对每个列名运行一个查询。
一个示例查询是select 'cola',count(cola) from count_nulls。第一个匹配项是文字'cola',因此需要quote_literal(cols.column_name),第二个匹配项是列名,因此需要使用quote_ident(cols.column_name)
select 'cola',count(cola) from count_nulls将对列“所有非空值”进行计数。如果列“所有值”为空,则返回0。
下面的函数将返回预期的结果。可以简化,因为我使用了很多提高通知。

CREATE OR REPLACE FUNCTION get_all_nulls (_table text)
    RETURNS TABLE (
        column_name_ text,
        numberofnull bigint
    )
    AS $body$
DECLARE
    cols RECORD;
    _sql text;
    _table_exists boolean;
    _table_reg regclass;
BEGIN
    _table_reg := _table::regclass;
    _table_exists := (
        SELECT
            EXISTS (
                SELECT
                FROM
                    pg_tables
                WHERE
                    schemaname = 'public'
                    AND tablename = _table));
    FOR cols IN
    SELECT
        column_name
    FROM
        information_schema.columns
    WHERE
        table_name = _table
        AND table_schema = 'public' LOOP
            _sql := 'select ' || quote_literal(cols.column_name) || ',count(' || quote_ident(cols.column_name) || ') from ' || quote_ident(_table::text);
            RAISE NOTICE '_sql:%', _sql;
            RETURN query EXECUTE _sql;
        END LOOP;
END;
$body$ STRICT
LANGUAGE plpgsql;

设置.

begin;
create table count_nulls(cola int, colb int, colc int);
INSERT into count_nulls values(null,null,null);
INSERT into count_nulls values(1,null,null);
INSERT into count_nulls values(2,3,null);
commit;

相关问题