SQL Pretty Printer
Beautify nested SELECT, JOIN, and UNION statements using structured SQL formatting rules.
Read a dense query one clause at a time
The SQL Pretty Printer is a quick clause separator for compact SQL. It starts with an editable sample in Raw SQL query and continuously writes a normalized version into Pretty Printed SQL. The transformation collapses repeated whitespace, capitalizes a defined set of keywords, and starts recognized clauses on new lines. It is best suited to a one-line SELECT that needs enough structure for review, a support ticket, or a code discussion.
This tool deliberately has a small surface: one input editor, one read-only output editor, and Copy. There are no dialect, indentation, keyword-case, comma-placement, or tab-width settings. Describing it accurately matters because a full SQL beautifier normally parses an abstract syntax tree; this formatter performs case-insensitive text replacement around selected keyword phrases.
The fastest route from log line to readable SQL
Replace the sample query in Raw SQL query with the statement you want to inspect. Formatting occurs immediately after each edit. Empty or whitespace-only input clears the result. When the output is useful, press Copy in the result header. The label changes to Copied for about two seconds, and then returns to Copy.
The default input demonstrates the intended use:
SELECT id,name,email FROM users WHERE active=1 ORDER BY created_at DESC LIMIT 10
Its result is:
SELECT id,name,email
FROM users
WHERE active=1
ORDER BY created_at DESC
LIMIT 10
The printer does not insert spaces after commas, around operators, or between function arguments. It does not add a semicolon. It preserves the original non-keyword spelling and punctuation after first reducing all whitespace runs to a single ordinary space.
For an implementation workflow, paste a captured statement, scan the clause boundaries, copy the result into a scratch file, and then make any deeper style changes with your project formatter. If the query will run, verify it against the target engine rather than treating readable layout as validation.
Recognized clause vocabulary
The formatter recognizes these phrases: SELECT, FROM, WHERE, ORDER BY, LIMIT, LEFT JOIN, INNER JOIN, RIGHT JOIN, JOIN, GROUP BY, and HAVING. Matching ignores case and requires word boundaries. Recognized text is emitted in uppercase and prefixed with a newline, then leading whitespace is trimmed from the final result.
That vocabulary covers common reporting queries:
select department_id,count(*) from employees where active=true group by department_id having count(*)>5 order by department_id
becomes:
SELECT department_id,count(*)
FROM employees
WHERE active=true
GROUP BY department_id
HAVING count(*)>5
ORDER BY department_id
The output is intentionally shallow. Selected columns remain on one line. Boolean expressions are not split at AND or OR. Subqueries receive the same global clause breaks but no indentation that communicates nesting. This makes the result compact and scannable without pretending to enforce a comprehensive SQL style guide.
An unusual consequence of replacement order
Keyword replacement happens sequentially. Specific joins are processed before the generic JOIN, but the later generic pass can match the JOIN word in an already formatted LEFT JOIN, INNER JOIN, or RIGHT JOIN. The result may split the phrase:
SELECT u.id,o.id
FROM users u
LEFT
JOIN orders o ON o.user_id=u.id
That is a known property of this lightweight pretty printer, not meaningful SQL syntax restructuring. The statement generally remains whitespace-equivalent, but the visual line is less polished than output from a parser-based formatter. Plain JOIN receives a line break as expected. There is no special token for FULL JOIN, CROSS JOIN, or NATURAL JOIN; only the JOIN portion is recognized.
Replacement also does not protect strings or comments. A value such as 'order by phone' can be changed to contain a newline and uppercase phrase inside the literal. Although many databases allow a literal newline, that is a semantic alteration of the stored value. A comment containing keywords can similarly be rearranged. Do not use this tool unchanged on statements whose literals or comments include recognized clause words.
Review workflow for production queries
Use formatting as the first pass, not the final assurance. Begin by obtaining the parameterized SQL and a separate parameter list; avoid copying customer secrets from logs. Pretty-print the SQL, then identify the major data flow: source tables, join predicates, row filters, grouping, aggregate filters, sorting, and limits. Manually indent subqueries or common table expressions in an editor if nesting matters.
Next, validate the statement with a dialect-aware parser or the target database. Run EXPLAIN or the engine’s plan command where appropriate. Formatting can expose a missing predicate to a human reader, but it cannot know whether a join is selective, an index exists, or an identifier resolves. For UPDATE and DELETE, use a transaction and confirm the WHERE condition before execution.
Finally, apply the repository’s canonical formatter before committing. Team rules may require leading commas, lowercase keywords, two-space indentation, aligned aliases, or one selected expression per line. This page has no controls for those choices, so its output should not silently replace established conventions.
Good fits and poor fits
Good inputs are ordinary ad hoc SELECT statements, query-builder output, compact snippets copied from application logs, and examples that need basic SQL clause formatting online. It is also useful when teaching clause order because the result visually separates FROM, WHERE, GROUP BY, HAVING, ORDER BY, and LIMIT.
Poor inputs include stored procedures, triggers, vendor migration scripts, PostgreSQL dollar-quoted bodies, and statements with keyword-like text literals. The recognized list does not include WITH, UNION, UNION ALL, INSERT, VALUES, UPDATE, SET, DELETE, RETURNING, OFFSET, FETCH, WINDOW, QUALIFY, or FOR UPDATE. Such words remain inline unless another recognized clause follows them.
The utility also does not understand comments, quoted identifiers, escape rules, or delimiter changes. It cannot choose between MySQL, PostgreSQL, SQLite, SQL Server, Oracle, BigQuery, or Snowflake grammar. It performs no syntax checking and does not connect to a database. “Pretty Printed SQL” means transformed text, not confirmed-valid SQL.
Failure modes worth spotting
A few output patterns deserve immediate inspection:
- A newline appears inside a quoted string because the string contained
select,from, or another recognized phrase. LEFT JOIN,INNER JOIN, orRIGHT JOINappears split across two lines due to the generic join pass.- A nested query is flush-left, obscuring its relationship to the outer query.
ORDERandBYseparated by unusual comments or punctuation are not recognized asORDER BY.- A statement uses
FULL OUTER JOIN; only the finalJOINword moves. - Whitespace significant to a client directive or templating language is collapsed.
- A multiline comment becomes one line before keyword replacements add new breaks within it.
If any of these affects correctness or readability, retain the source and switch to a parser-backed, dialect-specific SQL formatter. Never execute transformed data-changing SQL solely because it looks cleaner.
Building a clear example by hand
Suppose an incident log contains:
select p.sku,sum(i.quantity) from products p inner join invoice_items i on i.product_id=p.id where p.archived=false group by p.sku having sum(i.quantity)>100 order by sum(i.quantity) desc limit 25
The tool will expose each recognized clause, making the aggregate flow easier to scan. It will not place sum(i.quantity) on a separate selection line, indent the join, or explain that the HAVING predicate runs after grouping. A reviewer can use the line boundaries as landmarks, then manually format the select list and join condition. This division of labor is the right expectation: rapid normalization first, semantic review second.
When sharing the result, include the database dialect and version separately. Seemingly universal syntax can differ in identifier quoting, limits, booleans, and functions. If parameter placeholders were replaced for debugging, remove or anonymize personal data before copying.
FAQ
Does the SQL Pretty Printer validate syntax?
No. It recognizes text phrases and changes whitespace and keyword case. It does not parse, execute, or resolve the query.
Can I choose lowercase keywords or indentation width?
No. Recognized keywords become uppercase, and clauses are introduced with newlines. There are no style controls.
Why did words inside my string change?
The replacement is not quote-aware. A recognized keyword phrase inside a literal can be uppercased and preceded by a newline. Use a parser-aware formatter for that input.
Which joins receive explicit handling?
LEFT JOIN, INNER JOIN, RIGHT JOIN, and generic JOIN are in the keyword list. The generic pass may place JOIN on another line even after a specific join was matched.
Does Copy include the raw query?
No. Copy writes the current Pretty Printed SQL output to the clipboard.
Can it format several statements at once?
It will transform all supplied text, but it has no statement-level parsing or semicolon layout. Review multi-statement scripts carefully and prefer a full formatter for migrations.