¿Te refieres a una tabla en particular, o todas las tablas en un esquema?
Jack Douglas
1
¿Por qué necesitarías hacer eso? Parece que tiene demasiadas columnas / tablas y debería repensar su diseño.
eevar
Respuestas:
13
banco de pruebas:
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;
función:
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;$$;
consulta:
select table_schema, table_name, column_name,
has_nonnulls(table_schema, table_name, column_name)from information_schema.columns
where table_schema='stack';
resultado:
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)
Además, puede obtener una respuesta aproximada consultando el catálogo: si null_fraces cero, eso indica que no hay valores nulos, pero debe verificarse dos veces con los datos 'reales':
Esta es una vieja pregunta, pero las personas que usan extensiones espaciales (postgis) deben tener en cuenta que las columnas espaciales vacías no aparecen pg_statssi están vacías en la creación de la tabla. Descubrí esto hoy cuando hago algunas tareas de limpieza. Descubrí que algunas tablas históricas espaciales se habían importado usando ogr2ogr. si no hay una columna espacial en los datos que se importan, ogr2ogrcrea una columna de geometría llena de <NULL>. Mi pg_statsno tiene columnas de geometría de las tablas espaciales importadas (tiene todas las otras columnas para esas tablas). Bastante extraño, pensé.
GT.
6
En Postgresql, puede obtener los datos directamente de las estadísticas:
vacuum analyze;-- if neededselect schemaname, tablename, attname
from pg_stats
where most_common_vals isnulland most_common_freqs isnulland histogram_bounds isnulland correlation isnulland null_frac =1;
Es posible que obtenga algunos falsos positivos, por lo que es necesario volver a verificar después de encontrar a los candidatos.
¿Necesita alguna otra condición que no sea null_frac=1?
Jack Douglas
No estoy seguro. null_frac presumiblemente es real, por lo que podría ser que se redondea a 1 en algunos casos extraños. Pero incluso con 1 de cada 10k filas, daría lugar a algo que encaja.
Denis de Bernardy
1
Le mostraré mi solución en T-SQL, trabajando para SQL Server 2008. No estoy familiarizado con PostgreSQL, pero espero que encuentre alguna guía en mi solución.
-- 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);
En resumen, lo que hice fue crear una tabla de prueba con 5 columnas, generando ID y testTime por identidad y función getdate (), mientras que las 3 columnas varchar son las de interés. Uno tendrá solo valores NULL, uno no tendrá NULL, el otro será una columna combinada. El resultado final del script será que el script informará que la columna nullColumn tiene todas las filas NULL.
La idea era calcular la función DATALENGTH para cada columna (calcula el número de bytes para una expresión dada). Así que calculé el valor de DATALENGTH para cada fila de cada columna e hice una SUMA por columna. Si la SUMA por columna es NULL, entonces la columna completa tiene filas NULL, de lo contrario, hay algunos datos dentro.
Ahora tiene que encontrar la traducción para PostgreSQL y esperamos que un colega pueda ayudarlo con eso. O tal vez hay una buena vista del sistema que mostrará lo tonto que soy por reinventar la rueda :-).
Necesita consultar el catálogo de información para dicha información:
SELECT column_name FROM information_schema.columns WHERE table_name='your_table'
le da las tablas coincidentes para sus columnas.
No tengo una instalación de Postgres actualmente disponible, pero el resto debería ser simple
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
Esto está funcionando, pero es un enfoque iterativo :-). Prefiero el enfoque basado en conjuntos.
Marian
0
Después de combinar varios recursos, se me ocurrió esta función y consulta para encontrar todas las columnas vacías en todas las tablas de la base de datos
CREATEOR REPLACE FUNCTIONpublic.isEmptyColumn(IN table_name varchar,IN column_name varchar)
RETURNS boolean AS$$declare
count integer;BEGINexecute 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 NOTLIKE'pg_%')AND(public.isEmptyColumn(s.table_name, s.column_name))
Respuestas:
banco de pruebas:
función:
consulta:
resultado:
Además, puede obtener una respuesta aproximada consultando el catálogo: si
null_frac
es cero, eso indica que no hay valores nulos, pero debe verificarse dos veces con los datos 'reales':fuente
pg_stats
si están vacías en la creación de la tabla. Descubrí esto hoy cuando hago algunas tareas de limpieza. Descubrí que algunas tablas históricas espaciales se habían importado usandoogr2ogr
. si no hay una columna espacial en los datos que se importan,ogr2ogr
crea una columna de geometría llena de<NULL>
. Mipg_stats
no tiene columnas de geometría de las tablas espaciales importadas (tiene todas las otras columnas para esas tablas). Bastante extraño, pensé.En Postgresql, puede obtener los datos directamente de las estadísticas:
Es posible que obtenga algunos falsos positivos, por lo que es necesario volver a verificar después de encontrar a los candidatos.
fuente
null_frac=1
?Le mostraré mi solución en T-SQL, trabajando para SQL Server 2008. No estoy familiarizado con PostgreSQL, pero espero que encuentre alguna guía en mi solución.
En resumen, lo que hice fue crear una tabla de prueba con 5 columnas, generando ID y testTime por identidad y función getdate (), mientras que las 3 columnas varchar son las de interés. Uno tendrá solo valores NULL, uno no tendrá NULL, el otro será una columna combinada. El resultado final del script será que el script informará que la columna nullColumn tiene todas las filas NULL.
La idea era calcular la función DATALENGTH para cada columna (calcula el número de bytes para una expresión dada). Así que calculé el valor de DATALENGTH para cada fila de cada columna e hice una SUMA por columna. Si la SUMA por columna es NULL, entonces la columna completa tiene filas NULL, de lo contrario, hay algunos datos dentro.
Ahora tiene que encontrar la traducción para PostgreSQL y esperamos que un colega pueda ayudarlo con eso. O tal vez hay una buena vista del sistema que mostrará lo tonto que soy por reinventar la rueda :-).
fuente
Necesita consultar el catálogo de información para dicha información:
le da las tablas coincidentes para sus columnas.
No tengo una instalación de Postgres actualmente disponible, pero el resto debería ser simple
fuente
Después de combinar varios recursos, se me ocurrió esta función y consulta para encontrar todas las columnas vacías en todas las tablas de la base de datos
Disfruta :)
fuente