A MySQL formatter that reads MySQL
This MySQL formatter lays out a query with one clause per line and indented subqueries, but it reads
the text by MySQL's rules rather than the SQL standard's. That difference is not cosmetic. A backtick,
a # and a double quote each mean something in MySQL that they do not mean elsewhere, and a generic
formatter that gets them wrong can split a string or swallow half a line into a comment.
The panel above opens with a MySQL upsert already loaded. Paste your own query over it; the dialect stays on MySQL, and you can still switch keyword case, indentation or minify the result. Nothing is sent anywhere — the formatting happens in your browser.
Backtick identifiers
MySQL quotes identifiers with backticks. They are how a table called order or a column called
key can exist at all, since both are reserved words, and ORMs such as Laravel's query builder and
many dump tools put backticks around every name out of caution. The formatter treats everything
between two backticks as one token, including spaces and reserved words, and a doubled backtick
inside is an escaped backtick rather than the end of the name.
Double quotes are the trap. Without the ANSI_QUOTES SQL mode, "text" in MySQL is a string, not a
column. A query written for PostgreSQL that quotes column names with double quotes will run on MySQL
and compare against literal strings instead, usually returning nothing and raising no error.
Comments: # and the space after --
MySQL accepts three comment styles. /* ... */ works as everywhere else, and # starts a comment
that runs to the end of the line. The third is the one people trip on: -- only starts a comment when
a space or a line break follows it. That rule exists so that 5--1 means five minus minus one. A
formatter using standard rules would read it as 5 followed by a comment, and the output would drop
part of your expression without saying so.
Strings follow MySQL too. A backslash escapes the next character, so 'it\'s' is one string, and
that is also why a path like 'C:\new' holds a newline in MySQL.
LIMIT offset, count
LIMIT 20, 10 skips twenty rows and returns ten; the offset comes first. The formatter keeps both
numbers on the LIMIT line, which is where you want them when checking pagination. When a query
will outlive one database, LIMIT 10 OFFSET 20 says the same thing more plainly and also runs on
PostgreSQL.
ON DUPLICATE KEY UPDATE
MySQL's upsert is an INSERT with an ON DUPLICATE KEY UPDATE clause, and the formatter gives that
clause its own line with the assignments beneath it. Inside it, VALUES(col) is a function that
refers to the value the insert tried to write, not a new VALUES list, so it stays glued to its
parenthesis. On MySQL 8.0.20 and later, a row alias is the recommended replacement.
For queries that run on more than one database, the SQL formatter has the full list of layout rules, and the PostgreSQL formatter covers the other common dialect.