Просто интересно, есть ли быстрый способ подсчитать все значения NULL
(из всех столбцов) в таблице MySQL?Как подсчитать все значения NULL в таблице?
Спасибо за любую идею!
Просто интересно, есть ли быстрый способ подсчитать все значения NULL
(из всех столбцов) в таблице MySQL?Как подсчитать все значения NULL в таблице?
Спасибо за любую идею!
Если вы хотите, чтобы это сделано исключительно 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 [email protected] and [email protected];
-- 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 [email protected] and [email protected];
-- 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
В то время как первый один легко calcule команды:
SELECT count(*) FROM information_schema.columns where [email protected] and [email protected];
Во-вторых, 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. Нам нужно передать имя таблицы, но также имя базы данных, так как мы можем иметь одно и то же имя таблицы в отдельных базах данных.
Нам нужен запрос, который возвращает col1, col2, col3, COL4, col5 к нам на CONCAT_WS "строка"
Так что для этого запустить запрос
SELECT group_concat(column_name SEPARATOR ",") into @x from information_schema.columns where [email protected] and [email protected];
еще одна вещь, чтобы упомянуть , Когда мы использовали метод length() и replace(), чтобы узнать, сколько столбцов было объединено, мы должны убедиться, что у нас нет запятых среди значений. Но также обратите внимание, что мы можем иметь очень длинные ценности в наших ячейках базы данных. Для обоих этих трюков мы используем метод ASCII ('value'), который возвращает символ ASCII первого символа, который не может быть запятой и возвращает значение null для нулевых столбцов.
При этом мы можем скомпоновать все это в вышеупомянутом комплексном решении.
+1, хотя это немного сложно понять и поддерживать – Bozho
. Я добавил больше комментариев, и этот метод не нуждается в обслуживании, если он изменяет схему таблицы, он будет работать без изменения кода. Таким образом, его можно использовать повторно по другим причинам. – Pentium10
Это было очень долго и замечательно, и я решил проблему. Любое число при выполнении этой функции? Благодаря! – Nirmal
Что-то вроде
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
Это связано с пониманием количества столбцов для этой таблицы, на большой таблице это неэффективно. Проверьте мое решение. – Pentium10
@Pentium - вы говорите правду, есть способы обойти это. Для одноразового запроса достаточно простого регулярного выражения против вырезанного вывода DESCRIBE. Или запрос может быть создан из INFORMATION_SCHEMA. – APC
Вы действительно должны сделать это, используя не только SQL, но язык, который находится в вашем распоряжении:
Получить метаданные каждой таблицы - либо с помощью DESCRIBE table
, или используя встроенные функции метаданных в вашей технологии доступа к db
Создайте запросы следующего типа в цикле для каждого столбца п. (В псевдокоде)
int nulls = 0;
for (String colmnName : columNames) {
query = "SELECT COUNT(*) FROM tableName WHERE " + columnName + " IS NULL";
Result result = executeQuery(query);
nulls += result.size();
}
Это выполнит запрос выбора для каждого столбца, который может составлять сотни на большой таблице. Вы можете получить метаданные каждой таблицы и использовать их в SQL для получения нулевых значений в столбцах, проверьте мое решение. – Pentium10
мне кажется, что он делает единовременную статистику, поэтому он может позволить ему работать в течение целого дня, если необходимо :) – Bozho
Что-то вроде этого (заменить COL_COUNT в зависимости от обстоятельств):
select count(*) * COL_COUNT - count(col1) - count(col2) - ... - count(col_n) from table;
Это связано с пониманием количества столбцов для этой таблицы, на большой таблице это неэффективно. Проверьте мое решение. – Pentium10
Существует способ, которым вы можете достичь в MySQL исключительно с помощью SQL. Код не прост. Взгляните на решение, отправленное мной. – Pentium10