摘要
你知道数据库中如何用 SQL 统计某个表中所有列的空值情况吗?如果知道,别着急走开,继续看看跟您的方法有何异同。如果不知道,恭喜您来对地方了,下面跟着我一起去实现吧!
今天在数据库中处理缺失值时,我想统计表中每一列的空值情况,常规的方法就是用 COUNT 聚合函数结合 CASE WHEN ... 子句,这种方法的确可以实现,但是该方法要求表中有多少列,你的 SELECT 语句中就得写相应数量的列,每一列写一个 CASE WHEN... 子句。如果列数少的情况确实没问题,但是如果你的目标表包含数十上百列甚至更多,那阁下又应该如何应对呢?是不是继续按此方法写几十上百个 COUNT(CASE WHEN ...) 子句呢?原则上可行,但实际不可取。这种情况下,另一种明智的选择就是结合 Python,可以高效实现我们的目的。
接下来,我将分别讲讲常规的 SQL 实现和 ”Python+SQL“ 的高效简洁实现方法。
以 SQLite 数据库为例,假设我们在数据库中有一张表 HIV_dataset,现在我想处理缺失值,但我想一次性查询所有列的空值情况,实现方式如下:
-- Retrieve the number of null values for all columns
SELECT count(CASE WHEN Country IS NULL OR Country = 'Null' THEN 1 END) country_null_count,
count(CASE WHEN Year IS NULL
OR Year = 'Null'
OR Year = 0 THEN 1 END) year_null_count,
count(CASE WHEN PeopleLivingWithHIV IS NULL
OR PeopleLivingWithHIV = 'Null'
OR PeopleLivingWithHIV = 0 THEN 1 END) phiv_null_count,
count(CASE WHEN deaths_due_to_HIV IS NULL
OR deaths_due_to_HIV = 'Null'
OR deaths_due_to_HIV = 0 THEN 1 END) dhiv_null_count,
count(CASE WHEN Country_Population IS NULL
OR Country_Population = 'Null'
OR Country_Population = 0 THEN 1 END) cp_null_count,
count(CASE WHEN GDP_PerCapita IS NULL
OR GDP_PerCapita = 'Null'
OR GDP_PerCapita = 0 THEN 1 END) gdp_null_count,
count(CASE WHEN unemployment_rate IS NULL
OR unemployment_rate = 'Null'
OR unemployment_rate = 0 THEN 1 END) ur_null_count,
count(CASE WHEN School_enrollment_rate IS NULL
OR School_enrollment_rate = 'Null'
OR School_enrollment_rate = 0 THEN 1 END) ser_null_count,
count(CASE WHEN Women_living_with_HIV_Percentage IS NULL
OR Women_living_with_HIV_Percentage = 'Null'
OR Women_living_with_HIV_Percentage = 0 THEN 1 END) whiv_null_count,
count(CASE WHEN Mother_to_child_HIV_transmission_rate IS NULL
OR Mother_to_child_HIV_transmission_rate = 'Null'
OR Mother_to_child_HIV_transmission_rate = 0 THEN 1 END) mctr_null_count
FROM Hiv_dataset;
PS:我这里将0也算作空值,是由于业务本身特殊,实际上有些情况下0不算做缺失值,所以0能不能算作空值,得根据实际情况而定。数据库中正常情况下判断空值的条件应该是”真正的空值(
IS NULL)、空字符串“或者像我这里的字符串”Null“,所以判空条件是这几个条件的组合,用逻辑或(OR)连接,像这样:
SELECT COUNT(*)
WHERE COALESCE(column_name) = '' OR column_name = 'Null'
FROM table_name;
对于“Null”,如果你的数据中不同格式(大小写混合、全小写、全大写),那你可以采取将目标列全转换为小写再做判断,只需把
column_name = 'Null'条件改成lower(column_name) = 'null'即可。
回到原来的关注点,从上面的大段代码中你是否发现代码过于臃肿?每一列其实都是相同的实现语句,只是列名不同而已。这还是只是10列,正如之前所说,如果目标表有数十上百列甚至更多的话,你还通过这种方式吗?那显然不可取,而且显得很笨拙和臃肿。这个时候就轮到 Python 出场的时候啦。
在 Python 环境中,要统计数据库表中所有列的空值情况,可以通过循环迭代轻松实现,而且代码简洁高效,是字段数量较多时候的不二之选。同样以 SQLite 数据库为例,继续用前面的示例表,以下是实现方法:
import sqlite3
if __name__ == "__main__":
# The file path for database and table name
db_path = r"E:/Learning-Notes/LYX_Asignment/HIV_analysis.db"
table_name = "Hiv_dataset"
# Connect to sqlite database
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Get names of all columns for the specified table
cursor.execute(f"PRAGMA table_info({table_name})")
columns = [row[1] for row in cursor.fetchall()]
# Build a dynamic query that retrieves the number of all columns for table
null_count_query = (
"SELECT "
+ ", ".join(
[
f"COUNT(CASE WHEN {col} IS NULL OR {col} = 'Null' OR {col} = 0 THEN 1 END) AS {col}_null_count"
for col in columns
]
)
+ f" FROM {table_name}"
)
# Perfom the query
cursor.execute(null_count_query)
null_counts = cursor.fetchone()
# Print the results
print("The overview of missing values for all columns:")
for col, count in zip(columns, null_counts):
print(f"{col}: {count}")
# Close the connection
cursor.close()
conn.close()
从上面的输出可以看出,结果一目了然,且代码简洁高效。
好啦,关于如何统计数据库表中所有列的空值情况就分享到这里啦!如果您觉得这篇文章对您有用,请“点赞➕分享➕在看”支持我,同时让更多志同道合的朋友加入我们,一起学习,共同成长!还想获得更多数据分析相关技术知识?关注我,不迷路,数据路上踏正步(~~)


往期推荐⬇️⬇️⬇️
我用ChatGPT做了一次探索性数据分析,真的太太太实用了!
原文作者:数据派探险家;如有侵权,请联系管理员删除。