我如何获得 table 中所有列的计数 (*)?使用 PostgreSQL
How can i get a count(*) of all the columns in a table? Using PostgreSql
我有一堆 table,其中有几个有数百列。我需要计算每一列的非空值,我一直在手动进行。我想找出一种方法来获取 table 中所有列的所有计数。我查阅了 Whosebug 和 google,但无法找到答案。
我试过了,但它只是为每一列返回值 1。我知道它只是计算列数而不是每列中的值。有什么建议吗?
select count(COLUMN_NAME)
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name'
group by COLUMN_NAME
试试这个
SELECT
sum(case when column1 is not null then 1 else 0 end) as col1_not_null_count
sum(case when column2 is not null then 1 else 0 end) as col2_not_null_count
sum(case when column3 is not null then 1 else 0 end) as col3_not_null_count
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
我发现这样做的最佳方法是编写一个 case 语句,使列中的非空值变为 1,空值变为 0。然后我对 case 求和以获得计数非空值的数量:
SELECT SUM(CASE WHEN COLUMN_NAME1 IS NULL THEN 1 ELSE 0 END) AS COL1_COUNT
, SUM(CASE WHEN COLUMN_NAME2 IS NULL THEN 1 ELSE 0 END) AS COL2_COUNT
FROM TABLE_NAME
我在您的 select 中看到您正在查看 information_schema.columns table。您可以通过 select 从 table:
动态生成上面的代码
SELECT ', SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name + '_COUNT'
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
您还可以为相关 table 中的每一列动态创建不同的 select:
SELECT 'SELECT SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name + '_COUNT FROM ' + table_schema + '.' + table_name
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
没有什么神奇的方法可以做到这一点。如果您需要检查 100 个不同列中的每一列以查看有多少个非空值,则必须指定 table.
的每一列
您最多可以使用系统目录来帮助编写查询:
select 'SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name'
and is_nullable = 'YES'
如果您的列名中有空格或其他特殊字符,您可能需要添加带引号的标识符。
然后您可以将该输出复制到另一个查询并添加查询的缺失部分。我添加了 and is_nullable = 'YES'
因为检查 NOT NULL 列是浪费时间。据我所知,该列存在于 PostgreSQL 中。
COUNT(column_name)
始终为您提供 NON NULL
个值的计数。
创建一个像这样的通用函数,它可以将模式名称和 table 名称作为参数。
在这里,我正在构建由 UNION ALL
连接在一起的 select 语句,每个语句返回 column_name 的值,并且在动态执行时计算所有列。
CREATE OR REPLACE FUNCTION public.get_count( TEXT, TEXT )
RETURNS TABLE(t_column_name TEXT, t_count BIGINT )
LANGUAGE plpgsql
AS $BODY$
DECLARE
p_schema TEXT := ;
p_tabname TEXT := ;
v_sql_statement TEXT;
BEGIN
SELECT STRING_AGG( 'SELECT '''
|| column_name
|| ''','
|| ' count('
|| column_name
|| ') FROM '
|| table_schema
|| '.'
|| table_name
,' UNION ALL ' ) INTO v_sql_statement
FROM information_schema.columns
WHERE table_schema = p_schema
AND table_name = p_tabname;
IF v_sql_statement IS NOT NULL THEN
RETURN QUERY EXECUTE v_sql_statement;
END IF;
END
$BODY$;
执行
knayak=# select c.col, c.count from
public.get_count( 'public', 'employees' ) as c(col,count);
col | count
----------------+-------
employee_id | 107
first_name | 107
last_name | 107
email | 107
phone_number | 107
hire_date | 107
job_id | 107
salary | 107
commission_pct | 35
manager_id | 106
department_id | 106
(11 rows)
我来这里是为了回答同样的问题,但我想在不创建函数的情况下这样做,因为我并不总是能够在我正在使用的数据库中这样做。但是我使用的数据库安装了 tblfunc 模块,它具有交叉表功能,将 sql 字符串作为输入。我能够生成 sql,我可以在该函数中使用它来从任何 table 中获取所有列数。这是我使用的代码,我在其中输入了我想要的 schema_name 和 table_name:
select * from crosstab('select column_name, ''num'' as category, sum(num) from (' || (
select
string_agg(sql, '') as sql_string
from (
select
case when row_number() OVER () = 1 then '' else ' union all ' end ||
'select ''' || column_name || ''' as column_name, ' || 'count(' || column_name || ') as num from ' || table_schema || '.' || table_name as sql
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name') as sql_query limit 1
) || ') as column_counts group by column_name, category')
AS t(column_name text, num numeric) order by num asc
我有一堆 table,其中有几个有数百列。我需要计算每一列的非空值,我一直在手动进行。我想找出一种方法来获取 table 中所有列的所有计数。我查阅了 Whosebug 和 google,但无法找到答案。
我试过了,但它只是为每一列返回值 1。我知道它只是计算列数而不是每列中的值。有什么建议吗?
select count(COLUMN_NAME)
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name'
group by COLUMN_NAME
试试这个
SELECT
sum(case when column1 is not null then 1 else 0 end) as col1_not_null_count
sum(case when column2 is not null then 1 else 0 end) as col2_not_null_count
sum(case when column3 is not null then 1 else 0 end) as col3_not_null_count
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
我发现这样做的最佳方法是编写一个 case 语句,使列中的非空值变为 1,空值变为 0。然后我对 case 求和以获得计数非空值的数量:
SELECT SUM(CASE WHEN COLUMN_NAME1 IS NULL THEN 1 ELSE 0 END) AS COL1_COUNT
, SUM(CASE WHEN COLUMN_NAME2 IS NULL THEN 1 ELSE 0 END) AS COL2_COUNT
FROM TABLE_NAME
我在您的 select 中看到您正在查看 information_schema.columns table。您可以通过 select 从 table:
动态生成上面的代码SELECT ', SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name + '_COUNT'
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
您还可以为相关 table 中的每一列动态创建不同的 select:
SELECT 'SELECT SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name + '_COUNT FROM ' + table_schema + '.' + table_name
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
没有什么神奇的方法可以做到这一点。如果您需要检查 100 个不同列中的每一列以查看有多少个非空值,则必须指定 table.
的每一列您最多可以使用系统目录来帮助编写查询:
select 'SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name'
and is_nullable = 'YES'
如果您的列名中有空格或其他特殊字符,您可能需要添加带引号的标识符。
然后您可以将该输出复制到另一个查询并添加查询的缺失部分。我添加了 and is_nullable = 'YES'
因为检查 NOT NULL 列是浪费时间。据我所知,该列存在于 PostgreSQL 中。
COUNT(column_name)
始终为您提供 NON NULL
个值的计数。
创建一个像这样的通用函数,它可以将模式名称和 table 名称作为参数。
在这里,我正在构建由 UNION ALL
连接在一起的 select 语句,每个语句返回 column_name 的值,并且在动态执行时计算所有列。
CREATE OR REPLACE FUNCTION public.get_count( TEXT, TEXT )
RETURNS TABLE(t_column_name TEXT, t_count BIGINT )
LANGUAGE plpgsql
AS $BODY$
DECLARE
p_schema TEXT := ;
p_tabname TEXT := ;
v_sql_statement TEXT;
BEGIN
SELECT STRING_AGG( 'SELECT '''
|| column_name
|| ''','
|| ' count('
|| column_name
|| ') FROM '
|| table_schema
|| '.'
|| table_name
,' UNION ALL ' ) INTO v_sql_statement
FROM information_schema.columns
WHERE table_schema = p_schema
AND table_name = p_tabname;
IF v_sql_statement IS NOT NULL THEN
RETURN QUERY EXECUTE v_sql_statement;
END IF;
END
$BODY$;
执行
knayak=# select c.col, c.count from
public.get_count( 'public', 'employees' ) as c(col,count);
col | count
----------------+-------
employee_id | 107
first_name | 107
last_name | 107
email | 107
phone_number | 107
hire_date | 107
job_id | 107
salary | 107
commission_pct | 35
manager_id | 106
department_id | 106
(11 rows)
我来这里是为了回答同样的问题,但我想在不创建函数的情况下这样做,因为我并不总是能够在我正在使用的数据库中这样做。但是我使用的数据库安装了 tblfunc 模块,它具有交叉表功能,将 sql 字符串作为输入。我能够生成 sql,我可以在该函数中使用它来从任何 table 中获取所有列数。这是我使用的代码,我在其中输入了我想要的 schema_name 和 table_name:
select * from crosstab('select column_name, ''num'' as category, sum(num) from (' || (
select
string_agg(sql, '') as sql_string
from (
select
case when row_number() OVER () = 1 then '' else ' union all ' end ||
'select ''' || column_name || ''' as column_name, ' || 'count(' || column_name || ') as num from ' || table_schema || '.' || table_name as sql
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name') as sql_query limit 1
) || ') as column_counts group by column_name, category')
AS t(column_name text, num numeric) order by num asc