# How to Format SQL Like a Senior Engineer

> Pretty SQL is readable SQL. Learn the formatting rules senior engineers use (uppercase keywords, aligned columns, consistent indentation, no SELECT *), why they matter, and how to format any query automatically in your browser.

URL: https://uttir.com/blog/how-to-format-sql-like-a-senior-engineer
Published: 2026-08-21
Author: Uttir
Reading time: 5 min
Tags: sql, formatting, developer-tools, database, best-practices

## Quick answer

Pretty SQL is readable SQL, and readable SQL is debuggable SQL. The formatting rules senior engineers follow: uppercase keywords (SELECT, FROM, WHERE), one clause per line, indented subqueries and JOINs, aligned column lists in multi-line INSERTs, no SELECT * in production queries, explicit column aliases instead of relying on column order, and consistent naming (snake_case in tables and columns). The [Uttir SQL Formatter](/sql-formatter) applies all of these rules automatically in your browser.

Every team eventually has the SQL formatting debate. Some people use lowercase. Some use uppercase. Some indent with tabs, some with two spaces, some with four. Some put commas at the end of the line, some at the start. Some write `SELECT *` in production and sleep fine at night. Most of them, eventually, cause a bug.

Pretty SQL is readable SQL. Readable SQL is debuggable SQL. Debuggable SQL is the difference between a five-minute fix and a five-day hunt for a missing comma in a 600-line query. This post covers the formatting rules that experienced engineers actually follow, why they matter, and how to apply them to any query in seconds. The [Uttir SQL Formatter](/sql-formatter) applies all of them automatically, in your browser, with no upload.

## The short version

SQL formatting is not aesthetic. It is functional. The goal is to make every query readable by any engineer on the team, including the one who wrote it six months ago and no longer remembers what it does. The rules below are the ones that matter, in order of impact:

- Uppercase keywords. `SELECT`, `FROM`, `WHERE`, `JOIN`, `ON`, `GROUP BY`, `ORDER BY`, `LIMIT` are all SQL keywords. They are not user data. They should be visually distinct from user data, and uppercase does that.

- One major clause per line. `SELECT`, `FROM`, `WHERE`, `GROUP BY`, `ORDER BY`, `LIMIT` each get their own line.

- Consistent indentation. Subqueries, JOINs, and CASE expressions are indented 2 or 4 spaces (pick one and stick with it).

- No `SELECT *` in production. Always name the columns. New columns added to a table should not silently appear in your application's queries.

- Explicit aliases. Every derived column has an `AS some_name`. Every table in a JOIN has an alias. You should never have to count parentheses to know what a column refers to.

- snake_case for table and column names. Reserved for the data, not the formatting.

## An example

Here is the same query, before and after formatting:

**Before:**

```
select u.id, u.name, count(o.id) as orders, sum(o.total) as spent
from users u left join orders o on o.user_id = u.id
where u.created_at > '2026-01-01' and u.country = 'US'
group by u.id, u.name
having count(o.id) > 5
order by spent desc
limit 100
```

**After:**

```
SELECT
    u.id,
    u.name,
    COUNT(o.id) AS orders,
    SUM(o.total) AS spent
FROM users AS u
LEFT JOIN orders AS o
    ON o.user_id = u.id
WHERE
    u.created_at > '2026-01-01'
    AND u.country = 'US'
GROUP BY u.id, u.name
HAVING COUNT(o.id) > 5
ORDER BY spent DESC
LIMIT 100
```

The two queries are identical. The second is dramatically easier to scan. You can see at a glance which columns are selected, which tables are joined, which filters apply, and how the result is sorted and limited. The first query, you have to read every word to know what is going on.

The [Uttir SQL Formatter](/sql-formatter) produces output like this from any input query, with options for keyword case, indentation size, and whether to align column lists.

## Why these rules matter

Each rule has a reason.

**Uppercase keywords.** The eye finds uppercase shapes faster than lowercase, especially in long queries. A query that reads "SELECT name FROM users" lets you skim for "SELECT" and "FROM" without your eyes landing on the column and table names. Lowercase queries force you to read every word.

**One major clause per line.** A SQL query has a small number of major clauses (SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT). Putting each on its own line makes the query structure visible. When you have a bug, you can usually narrow it to one clause; if each clause is on its own line, you can read that clause in isolation.

**Consistent indentation.** Subqueries and JOINs introduce nesting. Indentation makes the nesting visible. Without indentation, a query with three nested subqueries is a wall of text. With indentation, the structure is obvious.

**No SELECT *.** Three reasons. First, it returns every column, which is wasteful if the application only needs two of them. Second, when the schema changes (a new column is added to the table), every `SELECT *` query silently starts returning the new column, which can break consumers that expect a fixed shape. Third, it makes the query harder to read — you have to look up the table schema to know what columns are returned.

**Explicit aliases.** Without aliases, you have to count commas and track the FROM clause to know which table a column belongs to. With aliases, the column reference makes the table obvious. `u.id` is the users table's id; `o.id` is the orders table's id. The cost of writing the alias is zero. The cost of not writing it is debugging time.

**snake_case names.** SQL is case-insensitive for keywords but case-sensitive for identifiers. `user_id` and `userId` are different columns. Picking one case convention and sticking to it prevents bugs from case mismatches and makes the codebase more consistent.

## Common patterns to know

Beyond the basic rules, a few patterns come up often enough to have a standard form.

**Multi-row INSERT.** When inserting more than one row, align the column list. It is much easier to scan and to spot a missing column.

```
INSERT INTO users (name, email, country, created_at) VALUES
    ('Alice', 'alice@example.com', 'US',  '2026-01-15'),
    ('Bob',   'bob@example.com',   'UK',  '2026-02-20'),
    ('Carol', 'carol@example.com', 'US',  '2026-03-10');
```

The [Uttir SQL Formatter](/sql-formatter) produces this style by default.

**JOIN chains.** When joining more than two tables, put each JOIN on its own line, with the ON condition indented.

```
SELECT
    u.id,
    u.name,
    o.id AS order_id,
    p.name AS product_name
FROM users AS u
INNER JOIN orders AS o
    ON o.user_id = u.id
INNER JOIN order_items AS oi
    ON oi.order_id = o.id
INNER JOIN products AS p
    ON p.id = oi.product_id
WHERE u.country = 'US'
```

**CTEs over nested subqueries.** Common Table Expressions (the `WITH` clause) are almost always more readable than nested subqueries. If you have more than one level of nesting, refactor to a CTE.

```
WITH active_users AS (
    SELECT id, name, country
    FROM users
    WHERE created_at > '2026-01-01'
),
us_orders AS (
    SELECT user_id, id AS order_id, total
    FROM orders
    WHERE country = 'US'
)
SELECT
    au.id,
    au.name,
    COUNT(uo.order_id) AS orders,
    SUM(uo.total) AS spent
FROM active_users AS au
LEFT JOIN us_orders AS uo
    ON uo.user_id = au.id
GROUP BY au.id, au.name
ORDER BY spent DESC
```

## How to keep the team consistent

The hardest part of SQL formatting is not learning the rules. It is getting the team to follow them. A few things that help:

- **Pre-commit hooks.** A formatter that runs on every commit, before the code review, removes the formatting discussion from reviews entirely. Reviewers can focus on logic, not whitespace.

- **Editor extensions.** SQL formatter extensions for VS Code, JetBrains, and other editors apply formatting on save. The author does not even have to think about it.

- **One formatter, configured the same way.** Pick a tool (sqlfluff, sql-formatter, sqlparse) and use the same config file across the team. The [Uttir SQL Formatter](/sql-formatter) is a good option for one-off queries and ad-hoc formatting; for CI pipelines, sqlfluff is the standard.

- **Lead by example.** When senior engineers format their SQL well, junior engineers learn from the codebase. When the codebase is full of inconsistently formatted queries, the formatting rules are invisible.

## Try it on your own query

Drop any query into the [Uttir SQL Formatter](/sql-formatter) and it will produce a consistently formatted version in your browser, with options for keyword case, indentation size, and column alignment. Nothing is uploaded; the query never leaves your device. The [JSON Formatter](/json-formatter) and [JSON Validator](/json-validator) are good companions if you are also debugging the data layer below the SQL.

## Related tools

- [SQL Formatter](https://uttir.com/sql-formatter) — Format and beautify SQL queries for MySQL, PostgreSQL, SQLite, and more — with optional keyword uppercase and tab indentation.
- [JSON Formatter](https://uttir.com/json-formatter) — Format, beautify, and validate JSON with adjustable indentation — instantly in your browser.
- [JSON Validator](https://uttir.com/json-validator) — Check whether your JSON is valid and find the exact line and column of any syntax error.
- [Regex Tester](https://uttir.com/regex-tester) — Test and debug regular expressions with live matches, capture groups, and highlighted results.

---

For the full HTML article, visit https://uttir.com/blog/how-to-format-sql-like-a-senior-engineer.
This file is the markdown rendering at https://uttir.com/blog/how-to-format-sql-like-a-senior-engineer.md. See https://uttir.com/llms.txt for a site-wide summary.
