Formatting preserves identifiers and aliases. Style suggestions are not database validation. Maximum input: 100,000 characters.

INPUT 0 characters, 0 lines
OUTPUT
Ctrl + Enter

Turning history off also clears saved queries. Shared links contain your SQL; only share queries you intend others to read.

Client-Side Only

SQL formatting happens locally in your browser. Analytics records usage metadata, not SQL text. See our privacy details.

9 Dialects

PostgreSQL, MySQL, SQL Server, BigQuery, SQLite, MariaDB, Redshift, and Snowflake.

Saves Settings

Your indent size, keyword case, and dialect preferences are saved locally between sessions.

Query History

Optionally keeps your last 5 queries in this browser. Turn history off or clear it at any time.

Ctrl+Enter Format
Ctrl+Shift+C Copy
Ctrl+Shift+Backspace Clear
Ctrl+] Indent
? Shortcuts

Free Online MySQL Formatter

This MySQL formatter instantly beautifies your MySQL queries, making them easier to read, debug, and maintain. Simply paste your unformatted query and click Format.

MySQL-Specific Formatting

Our formatter understands MySQL-specific syntax including:

  • Data Types: TINYINT, MEDIUMINT, DATETIME, TIMESTAMP, ENUM, SET
  • Functions: DATE_FORMAT, DATE_SUB, IFNULL, GROUP_CONCAT, FIND_IN_SET
  • Joins: STRAIGHT_JOIN, NATURAL JOIN syntax
  • Modifiers: SQL_CALC_FOUND_ROWS, HIGH_PRIORITY, LOW_PRIORITY
  • UPSERT: ON DUPLICATE KEY UPDATE syntax
  • Fulltext: MATCH AGAINST with IN BOOLEAN MODE

Why Format MySQL Queries?

MySQL is one of the most popular databases in the world, powering countless web applications. Clean, formatted queries help with:

  • Debugging slow queries and optimizing performance
  • Understanding complex JOIN operations
  • Reviewing queries in pull requests
  • Documentation and knowledge sharing

Worked examples

Backtick identifiers and ON DUPLICATE KEY UPDATE

Backtick-quoted names keep their exact spelling and case, which matters because MySQL table names are case-sensitive on Linux.

Before

insert into `UserStats` (`user_id`,`views`,`updated_at`) values (10,1,now()) on duplicate key update `views`=`views`+1,`updated_at`=now()

After

INSERT INTO
  `UserStats` (`user_id`, `views`, `updated_at`)
VALUES
  (10, 1, now())
ON DUPLICATE KEY UPDATE
  `views` = `views` + 1,
  `updated_at` = now()

Optimizer hints in executable comments

MySQL executable comments are real instructions, not notes. They are preserved verbatim rather than treated as dead text.

Before

select /*! STRAIGHT_JOIN */ u.id,u.name,count(o.id) as orders from users u left join orders o on o.user_id=u.id group by u.id,u.name having count(o.id)>5

After

SELECT
  /*! STRAIGHT_JOIN */ u.id,
  u.name,
  count(o.id) AS orders
FROM
  users u
  LEFT JOIN orders o ON o.user_id = u.id
GROUP BY
  u.id,
  u.name
HAVING
  count(o.id) > 5

GROUP_CONCAT with its own ORDER BY

GROUP_CONCAT carries a nested ORDER BY and SEPARATOR inside the call. Wrapping keeps the inner clause distinct from the outer query.

Before

select department,group_concat(name order by hire_date asc separator ', ') as team from employees where active=1 group by department

After

SELECT
  department,
  group_concat(
    name
    ORDER BY
      hire_date ASC SEPARATOR ', '
  ) AS team
FROM
  employees
WHERE
  active = 1
GROUP BY
  department

Other SQL Dialects

Need to format SQL for other databases? Try our formatters for PostgreSQL, SQL Server, BigQuery, or SQLite.

PostgreSQL MySQL SQL Server BigQuery SQLite MariaDB Redshift Snowflake