The numbers
table is a way to create an ad hoc table that consists of sequential integers.
mysql> SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4;
+---+
| n |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
+---+
These numbers are used to extract the N'th word from the comma-separated string. It's just a guess that 4 is enough to account for the number of words in the string.
The CHAR_LENGTH() expression is a tricky way to count the words in the command-separated string. The number of commas determines the number of words. So if you compare the length of the string to the length of that string with commas removed, it tells you the number of commas, and therefore the number of words.
mysql> set @string = 'a,b,c,d,e,f';
mysql> select char_length(@string) - char_length(replace(@string, ',', '')) + 1 as word_count;
+------------+
| word_count |
+------------+
| 6 |
+------------+
Confusing code like this is one of the many reasons it's a bad idea to store data in comma-separated strings.