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