sql >> Database teknologi >  >> RDS >> Mysql

Hvordan tæller man alle NULL-værdier i en tabel?

Hvis du vil have dette udelukkende udført af MYSQL og uden at opregne alle kolonnerne, så tag et kig på denne løsning.

I denne metode behøver du ikke at vedligeholde antallet af databasekolonner ved at hårdkode dem. Hvis dit tabelskema bliver ændret, vil denne metode fungere og kræver ikke kodeændring.

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 bruges til at undgå at læse, sammenkæde meget lange kolonner for ingenting, også ASCII gør os sikre for værdier, hvor det første tegn er et komma(,).

Da du arbejder med rapporter, kan du finde dette nyttigt, da det kan genbruges til hver tabel, hvis du indsætter en metode.

Jeg prøvede at give så mange kommentarer som muligt.

Lad os opdele i stykker ovenstående kompakte måde (omvendt):

Jeg ville ende med at have en forespørgsel som denne

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

Mens den første er nem at beregne ved at køre:

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

Den anden ikke-nullkolonner er en smule smertefuld. Efter en undersøgelse af de tilgængelige funktioner i MySQL, opdager vi, at CONCAT_WS ikke CONCAT null-værdier

Så kør en forespørgsel som denne:

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

Det er godt, vi fjerner null-værdierne fra opregningen. Men hvordan får vi ud af, hvor mange kolonner der rent faktisk var sammenkædet?

Jamen det er tricky. Vi er nødt til at beregne antallet af kommaer+1 for at få de faktisk sammenkædede kolonner.

Til dette trick brugte vi følgende SQL-notation

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

Ok, så vi har nu antallet af sammenkædede kolonner.

Men den sværere del kommer herefter.

Vi er nødt til at opregne for CONCAT_WS() alle værdier.
Vi skal have noget som dette:

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

Det er her, vi skal bruge de forberedte sætninger, da vi skal forberede en SQL-forespørgsel dynamisk fra endnu ukendte kolonner. Vi ved ikke, hvor mange kolonner der vil være i vores tabel.

Så til dette bruger vi data fra informationsskema-kolonner-tabellen. Vi skal videregive tabelnavnet, men også databasenavnet, da vi måske har det samme tabelnavn i separate databaser.

Vi har brug for en forespørgsel, der returnerer col1,col2,col3,col4,col5 til os på CONCAT_WS "strengen"

Så til dette kører vi en forespørgsel

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

Endnu en ting at nævne. Når vi brugte metoden length() og replace() til at finde ud af, hvor mange kolonner der var sammenkædet, skal vi sørge for, at vi ikke har kommaer blandt værdierne. Men vær også opmærksom på, at vi kan have rigtig lange værdier i vores databaseceller. Til begge disse tricks bruger vi metoden ASCII('værdi'), som vil returnere ASCII-tegn for det første tegn, som ikke kan være komma og vil returnere null for null-kolonner.

Når det er sagt, kan vi komprimere alt dette i ovenstående omfattende løsning.



  1. Hvordan forbinder man Android-app til MySQL-database?

  2. int(11) vs. int(alt andet)

  3. Få ugens startdato og ugens slutdato fra ugenummer

  4. Hvordan tilføjes ojdbc7 til Java-webapp fra Gradle?