Text arrives messy: a full name in one column, a code with the meaning buried in characters 4 to 6, a category that is sometimes "Retail" and sometimes " retail ". These 14 challenges are the three moves that fix it — pull a piece out, rewrite the value, match a shape — on real tables in your browser. Thirteen are free.
SUBSTR(col, 4, 3) takes three characters starting at the fourth; INSTR(col, '@') finds where a character sits so you can cut there instead of guessing an offset. Together they are how a domain comes out of an email, a year out of a text date, or a branch code out of an account number. LENGTH is the one that tells you the cut worked.
Counted from the challenge bank, September 2026. Easy first, then Medium, then Hard.
Uses: GROUP BY SUBSTR String Functions
The same category written three ways groups into three rows, and it is almost always whitespace or case. TRIM and UPPER collapse that before the GROUP BY sees it. || goes the other way and joins columns into one label, and GROUP_CONCAT folds a whole group into a single readable cell — the roster in one row rather than twelve.
Counted from the challenge bank, September 2026. Easy first, then Medium, then Hard.
Uses: GROUP BY SUBSTR String Functions
LIKE 'A%' anchors at the start, '%bank%' matches anywhere, and _ stands for exactly one character. The judgement is the anchor: a leading % means the database cannot use an index and has to read everything, which is fine on the tables here and matters on a real one.
Counted from the challenge bank, September 2026. Easy first, then Medium, then Hard.
String work is rarely the answer on its own — it is the step that makes the real question askable. Cleaning a category is what makes an aggregation group correctly; splitting a key is what lets a join find its match; and a text date has to become a real one before date functions can touch it. When the cleaning takes more than one step, name the steps with a CTE.