Chapter 04 · Reading Data with SELECT

Readable Query Formatting and Naming Conventions

Make SQL easy to inspect, test, review, and modify by treating formatting and naming as part of query correctness.

Beginner65–85 minutesStyle system + refactoring labLast reviewed: August 2026

Learning outcomes

SQL is executable documentation. Formatting does not usually change the statement’s meaning, but it strongly affects whether people can verify that meaning. A consistent style exposes missing predicates, ambiguous sources, accidental columns, and unsafe edits.

01

Format SELECT statements so clauses, expressions, and relationships are visually clear.

02

Choose table and column aliases that communicate role without excessive abbreviation.

03

Use comments and identifier conventions without creating hidden dependencies.

04

Refactor compressed or inconsistent SQL into a reviewable team style.

Readable SQL reduces reasoning cost

sql · difficult to review
select s.sale_id,p.product_name,s.quantity*p.unit_price*(1-s.discount_rate) net from sale s join product p on p.product_id=s.product_id;
sql · same meaning, visible structure
SELECT    s.sale_id,    p.product_name,    s.quantity * p.unit_price * (1 - s.discount_rate)        AS net_amountFROM sale AS sJOIN product AS p  ON p.product_id = s.product_id;

The second form reveals the output list, source relationship, calculation grouping, and result alias. A reviewer can inspect one concern at a time.

A practical formatting baseline

ElementRecommended baseline
Major clausesPlace SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY on separate lines
Select-list itemsOne expression per line when the list is nontrivial
IndentationUse one consistent width; this academy uses four spaces for continuation and two for join predicates
KeywordsUse a consistent case; examples use uppercase
CommasChoose a team convention and apply it consistently; examples use trailing commas between items
SemicolonsTerminate statements, especially in scripts and migration files
ParenthesesUse them to communicate intended grouping even when precedence is known
Blank linesSeparate logical statements or major CTE blocks, not every clause

There is no single universal visual style. Consistency and clarity matter more than arguing over uppercase versus lowercase keywords.

One select-list expression per line

sql · scan-friendly projection
SELECT    s.sale_id,    s.sold_at,    p.sku,    p.product_name,    s.quantity,    p.unit_price,    s.quantity * p.unit_price AS gross_amountFROM sale AS sJOIN product AS p  ON p.product_id = s.product_id;

This layout makes additions, removals, aliases, and code-review diffs easier to understand.

Alias names should communicate role

c

Short conventional alias

Useful when one customer source is present and the query is compact.

buyer

Role alias

Useful when the same entity appears in several roles, such as buyer and seller.

sales

Descriptive alias

Useful for derived tables or CTEs whose role is more important than physical source.

x

Opaque alias

Avoid unless the scope is extremely small and conventional mathematics is clearer.

sql · role-oriented aliases
SELECT    buyer.customer_id,    buyer.full_name AS buyer_nameFROM customer AS buyer;

Single-letter aliases are not automatically bad. They become bad when the reader cannot map them to a source or role.

Qualify columns in multi-source queries

Qualification prevents ambiguity and documents provenance.

sql · qualified names
SELECT    s.sale_id,    c.full_name AS customer_name,    p.product_name,    s.quantityFROM sale AS sJOIN customer AS c  ON c.customer_id = s.customer_idJOIN product AS p  ON p.product_id = s.product_id;

Even if a column name is currently unique across sources, qualification can protect readability when schemas evolve.

Identifier naming conventions

ConventionBenefitCaution
snake_casePortable and readable in many SQL toolsApply consistently
Singular table namesRows read naturally as one entity occurrencePlural is also valid if the team is consistent
Explicit key suffixescustomer_id communicates reference targetDo not encode changing data types in names
Unit suffixesduration_seconds prevents ambiguityKeep units aligned with stored meaning
Boolean-style namesis_active, has_access read as predicatesSome dialects lack a native Boolean type
Avoid reserved wordsReduces quoting and portability problemsCheck target engines and tooling

Names are long-lived interfaces. Prefer precise domain language over temporary UI labels.

Quoted identifiers create friction

sql · avoid names that require quoting
-- Legal in many engines, but awkward and case-sensitive in some.SELECT    "Order",    "Customer Name"FROM "Sales Data";
sql · portable ordinary identifiers
SELECT    sale_id,    customer_nameFROM sales_data;

Quoted identifiers are necessary in some legacy or integration contexts, but ordinary lower-case names with letters, digits, and underscores are easier to move across tools and engines.

Comments should explain why

sql · useful comments
-- The export uses public SKU rather than internal product_id-- because downstream systems do not share our surrogate keys.SELECT    p.sku,    p.product_name,    p.unit_priceFROM product AS p;

Comments that merely restate syntax become stale. Explain business assumptions, unusual compatibility choices, expected invariants, or deliberate performance tradeoffs.

Weak commentStronger comment
“Select products”“Use SKU as the cross-system identifier”
“Join customer”“Inner join is intentional: orphan sales are forbidden by the foreign key”
“Calculate total”“Discount rate is stored as a fraction from 0 to 1”

Keep related expressions aligned—but not artificially

sql · aligned aliases without excessive spacing
SELECT    p.sku          AS product_code,    p.product_name AS product_name,    p.unit_price   AS unit_priceFROM product AS p;

Light alignment can improve scanning in short blocks. Excessive spaces create noisy diffs when names change. Use formatters and team rules consistently.

Refactoring lab

Refactor this statement without changing its result:

sql · input to refactor
select s.sale_id,c.full_name,p.product_name,s.quantity,p.unit_price,s.quantity*p.unit_price*(1-s.discount_rate) total from sale s join customer c on c.customer_id=s.customer_id join product p on p.product_id=s.product_id;

A production-ready version:

sqlite · refactored query
SELECT    s.sale_id,    c.full_name AS customer_name,    p.product_name,    s.quantity,    p.unit_price,    s.quantity * p.unit_price * (1 - s.discount_rate)        AS net_amountFROM sale AS sJOIN customer AS c  ON c.customer_id = s.customer_idJOIN product AS p  ON p.product_id = s.product_id;

Run both versions against the same database and compare rows and column values. Formatting changes should not silently change semantics.

Review SQL by semantic layers

Output contract
Source tables
Relationships
Predicates
Grouping and order
Consumer assumptions

A structured review checks meaning layer by layer instead of reading the statement as one visual block.

Query review questions

  1. Can the reviewer identify every output column and its source?
  2. Are aliases meaningful and consistent?
  3. Are calculations grouped and named clearly?
  4. Are joins and predicates visually separated?
  5. Does the query rely on quoted or reserved identifiers unnecessarily?
  6. Do comments explain assumptions rather than restate syntax?
  7. Is the result contract stable for its consumer?
  8. Has the formatted version been tested against representative data?

Common style failures

Formatting by personal preference in every file

Team consistency is more valuable than individually perfect aesthetics. Automate the accepted style where practical.

Renaming columns only to shorten them

Aliases should clarify the result, not hide domain meaning.

Using comments instead of structure

A comment cannot rescue an ambiguous join or a forty-expression single line. Format and decompose the SQL first.

Changing style and logic together

Large mixed diffs are hard to review. Separate semantic changes from mechanical formatting when possible.

Chapter 4 summary

You can now construct clear read-only query results:

  • SELECT defines output expressions and FROM defines sources;
  • aliases create query-local source names and stable output labels;
  • explicit projections protect result contracts better than SELECT *;
  • DISTINCT removes equal output rows only when uniqueness is the actual requirement;
  • expressions and literals create computed columns without changing stored data;
  • consistent formatting and naming make SQL easier to verify and maintain.

Chapter 5 adds predicates, logical operators, pattern matching, sorting, and result limiting.

References

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.