답변:
테스트 베드 :
create role stack;
create schema authorization stack;
set role stack;
create table my_table as
select generate_series(0,9) as id, 1 as val1, null::integer as val2;
create table my_table2 as
select generate_series(0,9) as id, 1 as val1, null::integer as val2, 3 as val3;
함수:
create function has_nonnulls(p_schema in text, p_table in text, p_column in text)
returns boolean language plpgsql as $$
declare
b boolean;
begin
execute 'select exists(select * from '||
p_table||' where '||p_column||' is not null)' into b;
return b;
end;$$;
질문:
select table_schema, table_name, column_name,
has_nonnulls(table_schema, table_name, column_name)
from information_schema.columns
where table_schema='stack';
결과:
table_schema | table_name | column_name | has_nonnulls
--------------+------------+-------------+--------------
stack | my_table | id | t
stack | my_table | val1 | t
stack | my_table | val2 | f
stack | my_table2 | id | t
stack | my_table2 | val1 | t
stack | my_table2 | val2 | f
stack | my_table2 | val3 | t
(7 rows)
또한 카탈로그를 쿼리하여 대략적인 답변을 얻을 수 있습니다. null_frac
null이 아닌 '실제'데이터에 대해 다시 확인해야하는 0 인 경우 :
select tablename, attname, null_frac from pg_stats where schemaname='stack';
tablename | attname | null_frac
-----------+---------+-----------
my_table | id | 0
my_table | val1 | 0
my_table | val2 | 1
my_table2 | id | 0
my_table2 | val1 | 0
my_table2 | val2 | 1
my_table2 | val3 | 0
(7 rows)
pg_stats
은 테이블을 만들 때 빈 공간 열 이 비어 있으면 나타나지 않습니다 . 하우스 키핑을 할 때 오늘 이것을 발견했습니다. 일부 역사적인 aspatial 테이블을 사용하여 가져 왔음을 발견했습니다 ogr2ogr
. 가져올 데이터에 공간 열이 없으면로 ogr2ogr
가득 찬 형상 열을 만듭니다 <NULL>
. 내가 pg_stats
가져온 aspatial 테이블에서 어떤 형상 열이 없습니다 (이는 해당 테이블에 대한 다른 모든 열이 있습니다). 꽤 이상하다고 생각했다.
Postgresql에서는 통계에서 직접 데이터를 얻을 수 있습니다.
vacuum analyze; -- if needed
select schemaname, tablename, attname
from pg_stats
where most_common_vals is null
and most_common_freqs is null
and histogram_bounds is null
and correlation is null
and null_frac = 1;
오 탐지가 몇 번 나타날 수 있으므로 후보를 찾은 후 다시 검사해야합니다.
null_frac=1
?
SQL Server 2008에서 일하는 T-SQL 솔루션을 보여 드리겠습니다. PostgreSQL에 익숙하지 않지만 솔루션에 대한 지침을 찾을 수 있기를 바랍니다.
-- create test table
IF object_id ('dbo.TestTable') is not null
DROP table testTable
go
create table testTable (
id int identity primary key clustered,
nullColumn varchar(100) NULL,
notNullColumn varchar(100) not null,
combinedColumn varchar(100) NULL,
testTime datetime default getdate()
);
go
-- insert test data:
INSERT INTO testTable(nullColumn, notNullColumn, combinedColumn)
SELECT NULL, 'Test', 'Combination'
from sys.objects
union all
SELECT NULL, 'Test2', NULL
from sys.objects
select *
from testTable
-- FIXED SCRIPT FOR KNOWN TABLE (known structure) - find all completely NULL columns
select sum(datalength(id)) as SumColLength,
'id' as ColumnName
from dbo.testTable
UNION ALL
select sum(datalength(nullColumn)) as SumColLength,
'nullColumn' as ColumnName
from dbo.testTable
UNION ALL
select sum(datalength(notNullColumn)) as SumColLength,
'notNullColumn' as ColumnName
from dbo.testTable
UNION ALL
select sum(datalength(combinedColumn)) as SumColLength,
'combinedColumn' as ColumnName
from dbo.testTable
UNION ALL
select sum(datalength(testTime)) as SumColLength,
'testTime' as ColumnName
from dbo.testTable
-- DYNAMIC SCRIPT (unknown structure) - find all completely NULL columns
declare @sql varchar(max) = '', @tableName sysname = 'testTable';
SELECT @sql +=
'select sum(datalength(' + c.COLUMN_NAME + ')) as SumColLength,
''' + c.COLUMN_NAME + ''' as ColumnName
from ' + c.TABLE_SCHEMA + '.' + c.TABLE_NAME --as StatementToExecute
+ '
UNION ALL
'
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.TABLE_NAME = @tableName;
SET @sql = left(@sql, len(@sql)-11)
print @sql;
exec (@sql);
간단히 말해서, ID 및 testTime이 identity 및 getdate () 함수에 의해 생성되는 5 개의 열, 테스트 대상 테이블은 3 개의 varchar 열이 관심 대상인 테스트 테이블을 작성했습니다. 하나는 NULL 값만 있고 하나는 NULL이없고 다른 하나는 결합 된 열입니다. 스크립트의 최종 결과는 스크립트가 nullColumn 열을 모든 행이 NULL로보고한다는 것입니다.
아이디어는 함수 DATALENGTH 를 계산하는 것이 었습니다. 각 열에 대해 를 계산하는 것입니다 (주어진 표현식의 바이트 수를 계산 함). 그래서 각 열의 각 행에 대한 DATALENGTH 값을 계산하고 열 당 SUM을 만들었습니다. 열당 SUM이 NULL이면 전체 열에 NULL 행이 있고 그렇지 않으면 내부에 일부 데이터가있는 것입니다.
이제 PostgreSQL에 대한 번역을 찾아야하며 동료가이를 도와 줄 수 있기를 바랍니다. 또는 휠을 재발 명하는 데 얼마나 바보 같은지 보여주는 멋진 시스템보기가 있습니다 :-).
이러한 정보를 얻으려면 정보 카탈로그를 조회해야합니다.
SELECT column_name FROM information_schema.columns WHERE table_name='your_table'
열에 일치하는 테이블을 제공합니다.
현재 postgres 설치가 없지만 나머지는 간단해야합니다.
loop over the results of the above query and foreach result
send a COUNT(*) to the table
if the count is null, give back the column,
else ignore it
end foreach
여러 리소스에서 결합 한 후이 함수와 쿼리를 사용하여 모든 데이터베이스 테이블에서 모든 빈 열을 찾습니다.
CREATE OR REPLACE FUNCTION public.isEmptyColumn(IN table_name varchar, IN column_name varchar)
RETURNS boolean AS $$
declare
count integer;
BEGIN
execute FORMAT('SELECT COUNT(*) from %s WHERE %s IS NOT NULL', table_name, quote_ident(column_name)) into count;
RETURN (count = 0);
END; $$
LANGUAGE PLPGSQL;
SELECT s.table_name, s.column_name
FROM information_schema.columns s
WHERE (s.table_schema LIKE 'public') AND
(s.table_name NOT LIKE 'pg_%') AND
(public.isEmptyColumn(s.table_name, s.column_name))
즐겨 :)