Tool Lockers
Everyday online tools

Tool Lockers guide

SQL Formatting Best Practices: T-SQL, MySQL & PostgreSQL

Practical SQL formatting conventions for readable queries, joins, CTEs, and inserts across T-SQL, MySQL, and PostgreSQL.

By Tool Lockers

Readable SQL is easier to review, debug, and change safely. Consistent indentation makes the relationships between selected columns, joins, filters, and nested queries visible. A formatter can establish a starting layout, but formatting is not validation: the database engine, schema, and SQL dialect still determine whether a statement is valid and what it does.

This guide presents practical conventions for everyday queries and notes where T-SQL, MySQL, and PostgreSQL differ. You can try the SQL Formatter & Beautifier for a quick browser-based layout, then validate important statements with the matching database tools.

Start with a predictable clause layout

Put major clauses on separate lines and use a consistent indentation level for lists and nested expressions. A common pattern is:

SELECT
    customer_id,
    COUNT(*) AS order_count
FROM orders
WHERE status = 'paid'
GROUP BY customer_id
ORDER BY order_count DESC;

The important property is not whether commas appear at the end or beginning of a line; it is that the team uses one convention. Many teams put commas at the end of each selected expression because additions and removals are easy to diff. Others use leading commas because the delimiter is visually explicit. Agree on one style and apply it consistently.

Use meaningful aliases when they shorten repeated table names, but avoid aliases so cryptic that a reviewer must repeatedly look them up. Aligning one selected expression per line also makes it easier to spot duplicate columns, accidental omissions, and changes in output order.

Make joins and filters reviewable

Place each join on a new line and keep its condition close to the joined table:

SELECT
    o.order_id,
    c.customer_name,
    o.total
FROM orders AS o
INNER JOIN customers AS c
    ON c.customer_id = o.customer_id
WHERE o.status = 'open'
  AND o.created_at >= '2026-01-01'
ORDER BY o.created_at DESC;

This layout helps reviewers distinguish join conditions from row filters. When a query has several joins, keep the same indentation for each join and indent each ON expression. Parenthesize compound conditions when that makes precedence clearer; do not rely on a reader to remember how a long chain of AND and OR groups.

Keep filtering and grouping close to the data they affect. Format long predicates one per line, especially when they include optional branches. Avoid changing a predicate while reformatting: adding parentheses or moving an expression can change its meaning even when the intent appears obvious.

Format CTEs and nested queries

Common table expressions are useful when they give a stage of a query a clear name. Put each CTE on its own block, indent its body, and keep the final query separate:

WITH recent_orders AS (
    SELECT
        order_id,
        customer_id,
        total
    FROM orders
    WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT
    customer_id,
    SUM(total) AS recent_total
FROM recent_orders
GROUP BY customer_id;

For multiple CTEs, separate each named block with a comma and keep the comma placement consistent. Nested queries should be indented enough to reveal scope, but not so deeply that the right edge becomes difficult to scan. If the query has many nesting levels, consider whether an intermediate CTE or a simpler query structure would help.

Format INSERT statements carefully

List target columns explicitly and align values with the same order:

INSERT INTO products (sku, name, active)
VALUES ('A-10', 'Widget', TRUE);

For multiple rows, use one tuple per line. This makes column-value alignment easier to verify:

INSERT INTO products (sku, name, active)
VALUES
    ('A-10', 'Widget', TRUE),
    ('B-20', 'Gadget', FALSE);

Before execution, confirm the column list, value count, types, and intended conflict behavior. A formatter cannot establish whether a value is safe or appropriate for a production database.

Dialect notes: T-SQL, MySQL, and PostgreSQL

SQL formatting conventions overlap, but syntax does not. T-SQL uses features such as TOP, @variable names, bracketed identifiers, and GO batch separators. A formatter designed for generic clauses may not understand procedure blocks, temporary tables, or batches. Check scripts in SQL Server tooling and preserve batch boundaries.

MySQL supports backtick-quoted identifiers and dialect-specific functions and clauses. Confirm quoting, LIMIT usage, reserved words, and version-specific behavior. Backticks are not interchangeable with standard double-quoted identifiers in every configuration.

PostgreSQL supports constructs such as RETURNING, dollar-quoted strings, type casts, JSON operators, and rich common table expressions. Keep these expressions intact and validate them with PostgreSQL tools. A visual formatter should not change operators, string quoting, casts, or window definitions.

The browser formatter on Tool Lockers performs lightweight text formatting. It does not expose a dialect selector or run a database parser. It preserves quoted strings and comments while arranging recognized clauses, but it does not fully understand vendor-specific grammar. Use it for a first pass, not as the final authority on a migration or production query.

Keep formatting separate from query review

Formatting improves the text's presentation; it does not prove that the query is correct, efficient, secure, or safe to execute. After formatting, compare the output with the original. Check string literals, comments, identifier quoting, comma placement, parentheses, and the final semicolon. If a formatter changes tokens in a way that affects meaning, discard that output and validate the statement in a trusted SQL editor.

For important work, use version control to review the exact diff, run the statement against a representative test database, and inspect its execution plan where performance matters. Keep parameters bound by your application rather than building SQL by concatenating untrusted values. Formatting is one step in a careful review, not a substitute for one.

Frequently asked questions

How do I format SQL Server queries?

Use a T-SQL-aware formatter in your SQL Server environment for complete syntax support. A lightweight online formatter can make clauses more readable, but validate variables, GO batches, stored procedures, and SQL Server-specific syntax afterward.

Does formatting change query behavior?

Whitespace and keyword case are normally insignificant outside literals and comments, but a lightweight formatter is not a parser. Review any output before running it and do not assume semantic equivalence without checking.

Is my SQL sent to a server?

The Tool Lockers formatter runs in your browser and does not send the query to Tool Lockers or execute it against a database.

Can I format stored procedures?

You can paste stored procedure text for a readability pass, but nested procedural syntax and dialect-specific delimiters are not reliably understood. Use your database vendor's formatter or parser to validate the result.