Skip to main content
AllDevToolsHub
🗄️

SQL Formatter

100% Local

Beautify and format SQL queries for multiple dialects.

SQL Formatter
Dialect
Raw Query
Beautified Result

Query Optimization

Formats keywords to uppercase and applies consistent indentation for better readability and debugging.

Try:
This tool runs entirely in your browser. Your input is never uploaded, logged, or sent to AllDevToolsHub or anyone else, and it keeps working offline once the page has loaded.

Paste SQL to reformat with consistent indentation, keyword casing, and line breaks.

Overview

What is SQL Formatter?

Turn messy SQL queries into clean, readable, well-structured statements. Supports MySQL, PostgreSQL, and SQL Server with keyword casing and indent options.
FAQ

Frequently Asked Questions

Reference

Technical Deep Dive

SQL Formatter

Turn messy SQL queries into readable, well-structured statements. Supports MySQL, PostgreSQL, SQL Server, and generic SQL. Provides options for keywords casing and indentation.

sqlfluff enforces dialect rules in CI. This formatter is for a query you just pulled from logs and need to read, without uploading the table names.

Paste a single-line SELECT u.id,o.total FROM users u JOIN orders o ON o.user_id=u.id WHERE o.total>100. You should get clauses on their own lines.

Postgres ILIKE and SQL Server TOP are dialect-specific. Wrong dialect makes reserved-word highlighting lie.

01 Dialect Compatibility

Database Identifier Quote Unique Features Supported
PostgreSQL"double quotes":: cast, JSONB operators
MySQL`backticks`Index hints, STRAIGHT_JOIN
BigQuery`backticks`STRUCT, UNNEST, Project IDs
T-SQL[brackets]Table variables, CROSS APPLY

02 Formatting Principles

  • 📏
    Vertical Rhythm CTEs at the top, followed by the main SELECT. Each column on its own line to make Git diffs readable.
  • Keyword Casing Standardize on UPPERCASE for traditional readability or lowercase for modern dbt-style conventions.
  • 🔍
    Operator Alignment Boolean AND/OR placed at the start of new lines for logical clarity and easier debugging.

03 Why You're Pasting a Query In Here

Most of the SQL you'll format isn't yours, it's an ORM dump, a 200-line analytics view someone shipped years ago, or an EXPLAIN that needs to fit on one screen.

  • 🔍
    Code-reviewing a 200-line analytics query Half the comments on a SQL PR are about formatting. Run it through the formatter once and the discussion shifts to actual semantics, join correctness, NULL handling, window-function partitions.
  • 🤖
    Inspecting ORM-generated SQL Hibernate, SQLAlchemy, and ActiveRecord all emit single-line SQL with verbose alias names. Formatting reveals the N+1 in your includes chain or the eager-load that fanned out into 12 joins.
  • 📊
    Debugging EXPLAIN plans A formatted query lines up visually with the plan's join order, easier to see which subquery became the costly Seq Scan on a 50M-row table.
  • 📚
    Normalizing query history for similarity pg_stat_statements already normalizes; for raw slow-log dumps, formatting first makes it easier to group "same query, different literals" by visual diff.
  • 🧪
    Preparing snippets for docs & tickets A formatted query in a bug report saves the reviewer 30 seconds of mental parsing. Trivial, and the kind of trivial that compounds across a team.

04 Worked Examples

EXAMPLE 1 · SELECT LIST, COMMA-TRAILING vs COMMA-LEADING
Comma-trailing (most common, matches most style guides):
SELECT

u.id,
u.email,
u.created_at,
COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.email, u.created_at;


Comma-leading (favored by analytics teams, easier to comment lines out):

SELECT
u.id
, u.email
, u.created_at
, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.email, u.created_at;

Comma-leading lets you toggle a column on/off by commenting one line, no fiddly trailing-comma surgery. Pick a style and enforce it in the formatter; rotating between the two in one repo is the worst of both worlds.




EXAMPLE 2 · JOIN-CONDITION INDENT, STRIPE STYLE

Readable / default:

FROM orders o
INNER JOIN customers c ON c.id = o.customer_id
LEFT JOIN refunds r ON r.order_id = o.id AND r.status = 'completed'
LEFT JOIN payments p ON p.order_id = o.id AND p.captured_at IS NOT NULL

Aligned / "Stripe style", joins lined up so column relationships pop:

FROM       orders    o
INNER JOIN customers c ON c.id = o.customer_id
LEFT JOIN refunds r ON r.order_id = o.id
AND r.status = 'completed'
LEFT JOIN payments p ON p.order_id = o.id
AND p.captured_at IS NOT NULL

Aligned style takes more horizontal space but makes a 6-way join readable at a glance. Use it for views that need to live in a repo for years; the default style is fine for ad-hoc queries.




EXAMPLE 3 · NESTED CTE CHAINS

Three chained CTEs, formatting determines whether this is readable:

WITH active_users AS (
SELECT id, email FROM users WHERE deleted_at IS NULL
),
recent_orders AS (
SELECT
o.id,
o.user_id,
o.total
FROM orders o
WHERE o.created_at >= NOW() - INTERVAL '30 days'
),
summary AS (
SELECT
au.id,
au.email,
SUM(ro.total) AS spend_30d
FROM active_users au
LEFT JOIN recent_orders ro ON ro.user_id = au.id
GROUP BY au.id, au.email
)
SELECT * FROM summary WHERE spend_30d > 100;

Dialect note, quoting differs:

Postgres :  "user"           -- double quotes for identifiers
MySQL : `user` -- backticks
Snowflake: "USER" -- double quotes; case-folds UPPER by default
SQL Server: [user] -- square brackets (also "user")

A formatter that rewrites `user` to "user" will silently break a MySQL query when fed to a Postgres-aware tool. Always tell the formatter which dialect you're working in, or paste the dialect-specific output back to verify quoting survived.




05 Related Tools

Formatting is step one of any SQL workflow. These tools cover the steps that come next.

You Might Also Need