【问题标题】:How to find all columns in a database with all NULL values如何在数据库中查找所有具有 NULL 值的列
【发布时间】:2023-01-13 03:55:37
【问题描述】:
我有一个包含 70 多个表和 3000 多个字段的大型 Snowflake 数据库。有没有我可以在整个数据库中使用的查询来查找所有包含 NULL 的列?我有一个命令可以用来查找所有列
select * from prod_db.information_schema.columns
有没有办法修改该命令以识别哪些列全部为 NULL?如果没有办法在整个数据库中执行此操作。有没有办法在桌子上做到这一点?我不想输入:
select column_name from prod_db.information_schema.table_name
3000+次。谢谢!
【问题讨论】:
标签:
sql
null
snowflake-cloud-data-platform
snowflake-schema
【解决方案1】:
- 您可以为每一列生成一个 SELECT 查询列表,如下所示
选择 CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT('SELECT ''', TABLE_NAME), ''', '''), COLUMN_NAME), ''', '), 'COUNT(*) FROM '), TABLE_NAME), 'WHERE '), COLUMN_NAME), ' IS NULL OR '), LEN(COLUMN_NAME)), '= 0'), ' UNION ')
来自 information_schema.columns
- 然后可以获取并执行上述查询的结果以获得您需要的结果(PS:在执行之前删除步骤 1 生成的最后一行上的 UNION)
希望这可以帮助。
【解决方案2】:
这使用 SQL 生成器生成 SQL 语句,该语句将定位匹配两个条件的列:
- 该列位于具有一行或多行的表中
- 该列全部为空值。
为了提高效率,它没有检查整个表,而是使用 UNION ALL 块在每个表中查找单个非空行。它使用TOP 1 查找非空行。这样,一旦找到非空行,它就会返回该行。
这意味着大型 UNION ALL 部分将列出它找到非空行的表,这与我们想要的相反。要使用此信息,围绕 UNION ALL 的 CTE 将对信息模式中的列视图执行反连接。
with COLS as
(
select 'select top 1 ''' || C.TABLE_CATALOG || ''' as TABLE_CATALOG, ''' || C.TABLE_SCHEMA ||
''' as TABLE_SCHEMA, ''' || C.TABLE_NAME || ''' as TABLE_NAME, ''' || C.COLUMN_NAME ||
''' as COLUMN_NAME from "' ||
C.TABLE_CATALOG || '"."' || C.TABLE_SCHEMA || '"."' || C.TABLE_NAME || '"' ||
' where "' || C.COLUMN_NAME || '" is not null'
as NULL_CHECK
from INFORMATION_SCHEMA.COLUMNS C
left join INFORMATION_SCHEMA.TABLES T on
C.TABLE_CATALOG = T.TABLE_CATALOG and
C.TABLE_SCHEMA = T.TABLE_SCHEMA and
C.TABLE_NAME = T.TABLE_NAME
where C.IS_NULLABLE = 'YES' and T.TABLE_TYPE = 'BASE TABLE'
and T.ROW_COUNT > 0
), UNIONED as
(
select listagg(NULL_CHECK, '
union all
') as UNIONED from COLS
)
select replace($$
with NON_NULL_COLUMNS as (
!~UNIONED~!
)
select C.TABLE_CATALOG, C.TABLE_SCHEMA, C.TABLE_NAME, C.COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS C
left join NON_NULL_COLUMNS NN
on C.TABLE_CATALOG = NN.TABLE_CATALOG
and C.TABLE_SCHEMA = NN.TABLE_SCHEMA
and C.TABLE_NAME = NN.TABLE_NAME
and C.COLUMN_NAME = NN.COLUMN_NAME
left join INFORMATION_SCHEMA.TABLES T
on C.TABLE_CATALOG = T.TABLE_CATALOG
and C.TABLE_SCHEMA = T.TABLE_SCHEMA
and C.TABLE_NAME = T.TABLE_NAME
where NN.COLUMN_NAME is null and T.ROW_COUNT > 0
;$$, '!~UNIONED~!', UNIONED) as SQL_TO_RUN from UNIONED
;