web-dev-qa-db-ja.com

テーブル内のすべての列の数(*)を取得するにはどうすればよいですか? PostgreSqlの使用

私はいくつかのテーブルが何百もの列を持つテーブルをたくさん持っています。各列のnull以外の値の数を取得する必要があり、手動で実行しています。テーブルのすべての列のすべてのカウントを取得する方法を見つけたいと思います。私はstackoverflowとgoogleを調べましたが、答えを見つけることができませんでした。

私はこれを試しましたが、各列に対して値1を返すだけです。各列の値ではなく、列の数をカウントしているだけです。助言がありますか?

select count(COLUMN_NAME)
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name'
group by COLUMN_NAME
5
uclaastro

COUNT(column_name)は常にNON NULL値のカウントを提供します。

スキーマ名とテーブル名を引数として取ることができるこのようなジェネリック関数を作成します。

ここでは、UNION ALLsによって結合された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 := $1;
p_tabname       TEXT := $2;
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)
2
Kaushik Nayak

これを行う魔法の方法は実際にはありません。 100の異なる列のそれぞれをチェックして、null以外の値の数を確認する必要がある場合は、テーブルの各列を指定する必要があります。

できる最善の方法は、システムカタログを使用してクエリを作成することです。

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に存在します。

1
Bacon Bits

これを試して

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'
0
Rakesh Soni

これを行うために見つけた最良の方法は、列のnull以外の値を1にし、nullを0にするcaseステートメントを記述することです。次に、ケースを合計して、null以外の値を取得します値:

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テーブルを見ていることがわかります。上記のコードを動的に生成するには、そのテーブルから選択します。

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'

問題のテーブルのすべての列に対して異なる選択を動的に作成することもできます。

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'
0
danjuggler