Você quer dizer uma tabela específica ou todas as tabelas em um esquema?
Jack Douglas
1
Por que você precisaria fazer isso? Parece que você tem muitas colunas / tabelas e deve repensar seu design.
eevar
Respostas:
13
testbed:
create role stack;createschemaauthorization stack;set role stack;createtable my_table asselect generate_series(0,9)as id,1as val1,null::integer as val2;createtable my_table2 asselect generate_series(0,9)as id,1as val1,null::integer as val2,3as val3;
função:
createfunction has_nonnulls(p_schema in text, p_table in text, p_column in text)
returns boolean language plpgsql as$$declare
b boolean;beginexecute'select exists(select * from '||
p_table||' where '||p_column||' is not null)'into b;return b;end;$$;
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(7rows)
Além disso, você pode obter uma resposta aproximada consultando o catálogo - se null_fracfor zero que não indica nulos, mas deve ser verificado novamente com dados 'reais':
Esta é uma pergunta antiga, mas as pessoas que usam extensões espaciais (postgis) devem observar que colunas espaciais vazias não aparecem pg_statsse estiverem vazias na criação da tabela. Descobri isso hoje ao fazer algumas tarefas domésticas. Descobri que algumas tabelas espaciais históricas foram importadas usando ogr2ogr. se não houver nenhuma coluna espacial nos dados sendo importados, ogr2ogrcriará uma coluna de geometria cheia <NULL>. Meu pg_statsnão possui colunas geométricas das tabelas aspatiais importadas (ele tem todas as outras colunas para essas tabelas). Muito estranho, pensei.
GT.
6
No Postgresql, você pode obter os dados diretamente das estatísticas:
Você precisa de outras condições além disso null_frac=1?
Jack Douglas
Não tenho certeza. null_frac presumivelmente é real, então pode ser que arredonde para 1 em alguns casos estranhos. Mas mesmo com 1 de 10 mil linhas, isso resultaria em algo adequado.
Denis de Bernardy
1
Mostrarei minha solução em T-SQL, trabalhando para o SQL Server 2008. Não estou familiarizado com o PostgreSQL, mas espero que você encontre alguma orientação em minha solução.
-- create test tableIF object_id ('dbo.TestTable')isnotnullDROPtable testTable
go
createtable testTable (
id int identityprimarykeyclustered,
nullColumn varchar(100)NULL,
notNullColumn varchar(100)notnull,
combinedColumn varchar(100)NULL,
testTime datetime default getdate());
go
-- insert test data:INSERTINTO testTable(nullColumn, notNullColumn, combinedColumn)SELECTNULL,'Test','Combination'from sys.objects
unionallSELECTNULL,'Test2',NULLfrom sys.objects
select*from testTable
-- FIXED SCRIPT FOR KNOWN TABLE (known structure) - find all completely NULL columnsselect sum(datalength(id))as SumColLength,'id'as ColumnName
from dbo.testTable
UNIONALLselect sum(datalength(nullColumn))as SumColLength,'nullColumn'as ColumnName
from dbo.testTable
UNIONALLselect sum(datalength(notNullColumn))as SumColLength,'notNullColumn'as ColumnName
from dbo.testTable
UNIONALLselect sum(datalength(combinedColumn))as SumColLength,'combinedColumn'as ColumnName
from dbo.testTable
UNIONALLselect sum(datalength(testTime))as SumColLength,'testTime'as ColumnName
from dbo.testTable
-- DYNAMIC SCRIPT (unknown structure) - find all completely NULL columnsdeclare@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);
Em resumo, o que fiz foi criar uma tabela de teste com 5 colunas, sendo ID e testTime gerados pela função identity e getdate (), enquanto as 3 colunas varchar são as de interesse. Um terá apenas valores NULL, um não terá NULLs, o outro será uma coluna combinada. O resultado final do script será que ele reportará a coluna nullColumn como tendo todas as linhas NULL.
A ideia era calcular a função DATALENGTH para cada coluna (calcula o número de bytes para uma determinada expressão). Portanto, calculei o valor DATALENGTH para cada linha de cada coluna e fiz um SUM por coluna. Se o SUM por coluna for NULL, a coluna completa terá NULL linhas, caso contrário, existem alguns dados.
Agora você tem que encontrar a tradução para o PostgreSQL e espero que um colega possa ajudá-lo com isso. Ou talvez haja uma boa visão do sistema que mostre como sou burra por reinventar a roda :-).
Você precisa consultar o catálogo de informações para obter essas informações:
SELECT column_name FROM information_schema.columns WHERE table_name='your_table'
fornece as tabelas correspondentes para suas colunas.
Não tenho uma instalação do postgres atualmente em mãos, mas o resto deve ser simples
loop over the results of the above query and foreach result
send a COUNT(*)to the tableif the count isnull, give back the column,else ignore it
end foreach
Respostas:
testbed:
função:
inquerir:
resultado:
Além disso, você pode obter uma resposta aproximada consultando o catálogo - se
null_frac
for zero que não indica nulos, mas deve ser verificado novamente com dados 'reais':fonte
pg_stats
se estiverem vazias na criação da tabela. Descobri isso hoje ao fazer algumas tarefas domésticas. Descobri que algumas tabelas espaciais históricas foram importadas usandoogr2ogr
. se não houver nenhuma coluna espacial nos dados sendo importados,ogr2ogr
criará uma coluna de geometria cheia<NULL>
. Meupg_stats
não possui colunas geométricas das tabelas aspatiais importadas (ele tem todas as outras colunas para essas tabelas). Muito estranho, pensei.No Postgresql, você pode obter os dados diretamente das estatísticas:
Você pode obter alguns falsos positivos; portanto, é necessário fazer uma nova verificação depois de encontrar os candidatos.
fonte
null_frac=1
?Mostrarei minha solução em T-SQL, trabalhando para o SQL Server 2008. Não estou familiarizado com o PostgreSQL, mas espero que você encontre alguma orientação em minha solução.
Em resumo, o que fiz foi criar uma tabela de teste com 5 colunas, sendo ID e testTime gerados pela função identity e getdate (), enquanto as 3 colunas varchar são as de interesse. Um terá apenas valores NULL, um não terá NULLs, o outro será uma coluna combinada. O resultado final do script será que ele reportará a coluna nullColumn como tendo todas as linhas NULL.
A ideia era calcular a função DATALENGTH para cada coluna (calcula o número de bytes para uma determinada expressão). Portanto, calculei o valor DATALENGTH para cada linha de cada coluna e fiz um SUM por coluna. Se o SUM por coluna for NULL, a coluna completa terá NULL linhas, caso contrário, existem alguns dados.
Agora você tem que encontrar a tradução para o PostgreSQL e espero que um colega possa ajudá-lo com isso. Ou talvez haja uma boa visão do sistema que mostre como sou burra por reinventar a roda :-).
fonte
Você precisa consultar o catálogo de informações para obter essas informações:
fornece as tabelas correspondentes para suas colunas.
Não tenho uma instalação do postgres atualmente em mãos, mas o resto deve ser simples
fonte
Após combinar vários recursos, criei essa função e consulta para encontrar todas as colunas vazias em todas as tabelas do banco de dados
Desfrutar :)
fonte