MySQL SQL Formatter
Paste a MySQL query — including one copied straight out of application logs with ? placeholders still in it — and get readable, consistently formatted SQL. Backtick-quoted identifiers and MySQL-specific functions are preserved.
A MySQL query, before and after
The unformatted query below is the sample loaded into the editor above, and the output is exactly what this formatter returns for it with the default options. Nothing was tidied up by hand.
SELECT `u`.`id`, `u`.`name`, count(o.id) AS orders, sum(o.total) AS revenue FROM `users` `u` LEFT JOIN `orders` `o` ON o.user_id = u.id WHERE u.created_at >= ? AND u.status = ? AND o.region IN (?) GROUP BY u.id, u.name HAVING sum(o.total) > ? ORDER BY revenue DESC LIMIT 50 SELECT
`u`.`id`,
`u`.`name`,
count(o.id) AS orders,
sum(o.total) AS revenue
FROM
`users` `u`
LEFT JOIN `orders` `o` ON o.user_id = u.id
WHERE
u.created_at >= ?
AND u.status = ?
AND o.region IN (?)
GROUP BY
u.id,
u.name
HAVING
sum(o.total) > ?
ORDER BY
revenue DESC
LIMIT
50 MySQL syntax it handles
A generic formatter mangles dialect-specific syntax or refuses it outright. These are the MySQL constructs this formatter is tested against.
? Positional placeholders are grouped by the column and operator they sit against, so a column compared twice is filled once.
`identifier` Backtick-quoted identifiers keep their quoting and case.
ON DUPLICATE KEY UPDATE MySQL-only statement clauses are formatted rather than passed through as a blob.
STRAIGHT_JOIN MySQL join hints and index hints are preserved in place.
MySQL formatter FAQ
Can I paste a query with ? placeholders straight from my logs?
Yes. That is the common case. The ? placeholders are detected and grouped by the column they compare against, so a repeated column is filled once. You can then switch the output to filled SQL to get a runnable query.
Does this work for MariaDB too?
Yes — pick MariaDB from the dialect list for MariaDB-specific keywords, or use MySQL, which covers the shared syntax.
Does it preserve the case of backtick-quoted identifiers?
Yes. Keyword casing and identifier casing are separate options, so you can uppercase SELECT and JOIN while a column such as userProfile keeps its camelCase. That matters more on MySQL than elsewhere, because table-name case sensitivity depends on the host filesystem.
Can it minify a MySQL query back onto one line?
Yes. Minify collapses the query for pasting back into application code, and it never rewrites whitespace inside a string literal — so a comparison against a value with two spaces in it still matches the same rows after minifying.
Will it format a fragment pulled out of a log line?
Yes. A partial query — or a bare WHERE u.created_at >= ? AND u.status = ? — is formatted and made editable without the surrounding SELECT. That is the usual shape of MySQL slow-query and general-log output, so it is the case this formatter is built to survive.
Are ON DUPLICATE KEY UPDATE and index hints handled?
Yes. MySQL-only clauses are formatted as real clauses rather than passed through as one unformatted blob, and join or index hints such as STRAIGHT_JOIN and FORCE INDEX stay attached to the table they qualify.