Как посчитать все значения NULL в таблице? - PullRequest
4 голосов
/ 19 февраля 2010

Просто интересно, есть ли быстрый способ подсчитать все значения NULL (из всех столбцов) в таблице MySQL?

Спасибо за любую идею!

Ответы [ 4 ]

4 голосов
/ 19 февраля 2010

Если вы хотите, чтобы это делалось исключительно 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 делаетМы безопасны для значений, где первый символ представляет собой запятую (,).

Поскольку вы работаете с отчетами, это может оказаться полезным, так как это может быть повторно использовано для каждой таблицы, если вы добавите метод.

Я пытался разрешить как можно больше комментариев.

Давайте разделим на части описанный выше компактный способ (обратный путь):

Я хотел получить такой запрос

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;

Второй столбцы notnull - это немного больно.После изучения функций, доступных в 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.Нам нужно передать имя таблицы, а также имя базы данных, поскольку у нас может быть одно и то же имя таблицы в отдельных базах данных.

Нам нужен запрос, который возвращает нам col1, col2, col3, col4, col5 наCONCAT_WS "string"

Итак, для этого мы запустим запрос

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

Еще одна вещь, которую стоит упомянуть.Когда мы использовали метод length () и replace (), чтобы узнать, сколько столбцов было объединено, мы должны убедиться, что у нас нет запятых среди значений.Но также учтите, что в ячейках нашей базы данных могут быть действительно длинные значения.Для обоих этих приемов мы используем метод ASCII ('value'), который будет возвращать символ ASCII первого символа, который не может быть запятым, и будет возвращать ноль для пустых столбцов.

При этом мы можем сжатьвсе это в приведенном выше комплексном решении.

4 голосов
/ 19 февраля 2010

Что-то вроде

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
0 голосов
/ 19 февраля 2010

Примерно так (замените COL_COUNT соответствующим образом):

select count(*) * COL_COUNT - count(col1) - count(col2) - ... - count(col_n) from table;
0 голосов
/ 19 февраля 2010

Вы действительно должны сделать это, используя не только 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();
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...