sql >> Databáze >  >> RDS >> Mysql

Jak spočítat všechny hodnoty NULL v tabulce?

Pokud to chcete provádět výhradně pomocí MYSQL a bez výčtu všech sloupců, podívejte se na toto řešení.

Při této metodě nemusíte udržovat počet sloupců databáze jejich pevným kódováním. Pokud bude schéma vaší tabulky upraveno, bude tato metoda fungovat a nebude vyžadovat změnu kódu.

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 se používá k tomu, aby se zabránilo čtení, řetězení velmi dlouhých sloupců za nic, také ASCII nás činí bezpečnými pro hodnoty, kde první znak je čárka(,).

Protože pracujete s přehledy, může to být užitečné, protože to lze znovu použít pro každou tabulku, pokud zadáte metodu.

Snažil jsem se vložit co nejvíce komentářů.

Rozdělme se na kusy výše uvedeným kompaktním způsobem (obráceným způsobem):

Chtěl jsem skončit s dotazem jako je tento

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

Zatímco první lze snadno vypočítat spuštěním:

SELECT count(*) FROM information_schema.columns where [email protected] and [email protected];

Druhý sloupec není null je trochu bolestivý. Po částečném prozkoumání funkcí dostupných v MySQL jsme zjistili, že CONCAT_WS nemá CONCAT null hodnoty

Takže spusťte dotaz takto:

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

To je dobře, zbavíme se hodnot null z výčtu. Jak ale zjistíme, kolik sloupců bylo skutečně zřetězeno?

No to je ošemetné. Musíme vypočítat počet čárek+1, abychom získali skutečně zřetězené sloupce.

Pro tento trik jsme použili následující SQL notaci

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

Dobře, takže nyní máme počet zřetězených sloupců.

Ale ta těžší část teprve přijde.

Pro CONCAT_WS() musíme vyčíslit všechny hodnoty.
Potřebujeme mít něco takového:

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

Zde musíme využít připravené příkazy, protože SQL dotaz musíme připravit dynamicky z dosud neznámých sloupců. Nevíme, kolik sloupců bude v naší tabulce.

K tomu tedy používáme data z tabulky information_schema columns. Musíme předat název tabulky, ale také název databáze, protože můžeme mít stejný název tabulky v samostatných databázích.

Potřebujeme dotaz, který nám vrátí col1, col2, col3, col4, col5 na "řetězec" CONCAT_WS

Za tímto účelem spustíme dotaz

SELECT group_concat(column_name SEPARATOR ",") into @x from information_schema.columns where [email protected] and [email protected];

Ještě jedna věc, kterou je třeba zmínit. Když jsme pomocí metody length() a replace() zjistili, kolik sloupců bylo zřetězeno, musíme se ujistit, že mezi hodnotami nejsou čárky. Ale také si uvědomte, že v buňkách databáze můžeme mít opravdu dlouhé hodnoty. Pro oba tyto triky používáme metodu ASCII('value'), která vrátí ASCII znak prvního znaku, který nemůže být čárka a pro prázdné sloupce vrátí hodnotu null.

Jak již bylo řečeno, můžeme toto vše zkombinovat ve výše uvedeném komplexním řešení.



  1. Jak číst binární soubory protokolu MySQL (BinLog) pomocí mysqlbinlog

  2. Reverzní řetězec slovo po slovu pomocí SQL

  3. Rozdíl mezi FIELD() a FIND_IN_SET() v MySQL

  4. LEFT JOIN příkaz a limit