如何计算表中的所有NULL值?

时间:2010-02-19 09:50:51

标签: mysql count

只是想知道,有没有快速的方法来计算MySQL表中所有NULL值(来自所有列)?

感谢您的任何想法!

4 个答案:

答案 0 :(得分:4)

这样的东西
select id
       , sum ( case when col1 is null then 1 else 0 end case ) col1
       , sum ( case when col2 is null then 1 else 0 end case ) col2
       , sum ( case when col3 is null then 1 else 0 end case ) col3
from contacts
group by id

答案 1 :(得分:4)

如果您希望由MYSQL完全完成此操作,并且没有枚举所有列,请查看此解决方案。

在此方法中,您不必通过对其进行硬编码来维护数据库列的数量。如果您的表架构将被修改,则此方法将起作用,并且不需要更改代码。

SET @db = 'testing'; -- database
SET @tb = 'fuzzysearch'; -- table
SET @x = ''; -- will hold the column names with ASCII method applied to retrieve the number of the first char
SET @numcolumns = 0; -- will hold the number of columns in the table

-- figure out how many columns we have
SELECT count(*) into @numcolumns FROM information_schema.columns where table_name=@tb and table_schema=@db;

-- we have to prepare some query from all columns of the table
SELECT group_concat(CONCAT('ASCII(',column_name,')') SEPARATOR ",") into @x from information_schema.columns where table_name=@tb and table_schema=@db;
-- after this query we have a variable separated with comma like
-- ASCII(col1),ASCII(col2),ASCII(col3)

-- we now generate a query to concat the columns using comma as separator (null values are omitted from concat)
-- then figgure out how many times the comma is in that substring (this is done by using length(value)-length(replace(value,',',''))
-- the number returned is how many non null columns we have in that column
-- then we deduct the number from the known number of columns, calculated previously
-- the +1 is added because there is no comma for single value
SET @s = CONCAT('SELECT @numcolumns - (length(CONCAT_WS(\',\',', @x, '))-length(replace(CONCAT_WS(\',\',', @x, '),\',\',\'\')) + 1) FROM ',@db,'.',@tb,';');
PREPARE stmt FROM @s;
EXECUTE stmt;
-- after this execution we have returned for each row the number of null columns
-- I will leave to you to add a sum() group call if you want to find the null values for the whole table
DEALLOCATE PREPARE stmt;

ASCII用于避免读取,连接非常长的列,而ASCII也使我们对第一个char是逗号(,)的值安全。

由于您正在处理报告,因此您可能会发现这很有用,因为如果您放入方法,可以为每个表重复使用。

我试图尽可能多地发表评论。

让我们分成以上紧凑的方式(反向):

我想最终得到像这样的查询

SELECT totalcolumns - notnullcolumns from table; -- to return null columns for each row

虽然第一个很容易通过运行来计算:

SELECT count(*) FROM information_schema.columns where table_name=@tb and table_schema=@db;

第二个notnullcolumns有点痛苦。 在对MySQL中可用的函数进行检查之后,我们检测到CONCAT_WS没有CONCAT空值

所以运行这样的查询:

SELECT CONCAT_WS(",","First name",NULL,"Last Name");
returns: 'First name,Last Name'

这很好,我们从枚举中删除了空值。 但是我们如何获得实际连接的列数?

这很棘手。我们必须计算逗号的数量+ 1以获得实际连接的列。

对于这个技巧,我们使用了以下SQL表示法

select length(value)-length(replace(value,',','')) +1 from table

好的,我们现在拥有连接列的数量。

但接下来会有更难的部分。

我们必须枚举CONCAT_WS()所有值 我们需要这样的东西:

SELECT CONCAT_WS(",",col1,col2,col3,col4,col5);

这是我们必须使用预准备语句的地方,因为我们必须从未知的列动态准备SQL查询。我们不知道我们的表中会有多少列。

因此,我们使用来自information_schema列表的数据。我们需要传递表名,还要传递数据库名,因为我们在不同的数据库中可能有相同的表名。

我们需要一个查询,在CONCAT_WS“string”上将col1,col2,col3,col4,col5返回给我们

因此,我们运行查询

SELECT group_concat(column_name SEPARATOR ",") into @x from information_schema.columns where table_name=@tb and table_schema=@db;

还有一件事需要提及。当我们使用length()和replace()方法找出连接的列数时,我们必须确保我们的值之间没有逗号。但请注意,我们的数据库单元格中可以包含非常长的值。对于这两个技巧,我们使用方法ASCII('value'),它将返回第一个char的ASCII字符,它不能是逗号,并且将为null列返回null。

话虽如此,我们可以在上述综合解决方案中压缩所有这些。

答案 2 :(得分:0)

你真的应该使用SQL,而不是使用的语言:

  1. 获取每个表的元数据 - 使用DESCRIBE table,或使用数据库访问技术中的内置元数据功能

  2. 在每个列的循环中创建以下类型的查询。 (伪代码)

    int nulls = 0;
    for (String colmnName : columNames) {
        query = "SELECT COUNT(*) FROM tableName WHERE " + columnName + " IS NULL";
        Result result = executeQuery(query);
        nulls += result.size();
    }
    

答案 3 :(得分:0)

像这样的东西(适当地替换COL_COUNT):

select count(*) * COL_COUNT - count(col1) - count(col2) - ... - count(col_n) from table;