Chapter 04 · Reading Data with SELECT

Choosing Columns and Avoiding SELECT Star

Treat every selected column as part of a deliberate data contract rather than accepting whatever a table happens to contain.

Beginner65–85 minutesProjection design + contract labLast reviewed: August 2026

Learning outcomes

A query’s select list is an interface. Applications deserialize it, reports label it, exports preserve it, and people reason from it. SELECT * delegates that interface to the current source schema.

01

Explain what the star expansion means and why it can create unstable result contracts.

02

Choose explicit columns based on the consumer’s purpose, sensitivity, and type requirements.

03

Recognize performance, ambiguity, and schema-evolution risks associated with broad projections.

04

Refactor star-based queries into clear, testable output contracts.

What SELECT star means

sql · broad projection
SELECT *FROM customer;

The star is expanded to the columns available from the source. For one table it appears convenient, especially during exploration. But it does not express which columns the consumer actually needs.

*

Expansion

The source determines the returned column set.

C

Contract

Adding, removing, or reordering source columns can change the result shape.

D

Data exposure

New sensitive or internal columns may appear automatically.

R

Review cost

Readers must inspect the schema to know what the query returns.

Use purpose to choose columns

Start from the consumer’s question, not the table definition. A customer-picker interface may need an identifier and label. A billing export may need legal and financial fields. An operational diagnostic may temporarily need more.

ConsumerLikely projectionExcluded by default
Customer selectorcustomer_id, full_nameCity, segment, internal metadata
Catalogue cardsku, product_name, unit_priceInternal product ID if not needed
Sale event exportStable event fields in documented orderFuture columns and unrelated joins
Interactive investigationPossibly broad during explorationDo not promote exploratory star queries blindly
sqlite · purpose-driven projections
-- Customer picker.SELECT    c.customer_id,    c.full_nameFROM customer AS c;-- Product catalogue card.SELECT    p.sku,    p.product_name,    p.unit_priceFROM product AS p;

Schema evolution can change star output

Suppose an application expects four customer columns. Later, the schema adds an internal risk flag or an encrypted contact field. A star query may return the new column without any query change.

sqlite · demonstrate star expansion after evolution
CREATE TABLE customer_demo (    customer_id INTEGER PRIMARY KEY,    full_name   TEXT NOT NULL,    city        TEXT);INSERT INTO customer_demo VALUES (1, 'Nadia Rahimi', 'Tehran');SELECT * FROM customer_demo;ALTER TABLE customer_demoADD COLUMN internal_note TEXT;SELECT * FROM customer_demo;

The second query has a different shape. Explicit projections remain stable until the query author intentionally edits them.

Stable contract principle

A query used by production code, an API, a file export, or a scheduled report should normally list columns explicitly and in a deliberate order.

Column order is part of many interfaces

SQL consumers often access fields by name, but CSV exports, positional mappings, legacy drivers, and tests may depend on order. Explicit projection makes the order visible.

sqlite · same source, deliberate orders
-- Human-oriented order.SELECT    p.product_name,    p.sku,    p.unit_priceFROM product AS p;-- Machine contract order.SELECT    p.product_id,    p.sku,    p.product_name,    p.category,    p.unit_priceFROM product AS p;

Neither order is universally correct. The correct order is the documented order for that result contract.

Broad projections waste work

Returning unnecessary columns can increase data transfer, decoding, memory use, and exposure. Large text or binary values make the difference obvious, but the discipline matters even when the current tables are small.

Source rows
Read selected fields
Transfer result
Decode in client
Use a subset

An unnecessarily broad projection carries unused data through multiple layers.

The query optimizer may avoid some physical work depending on indexes and storage, but an explicit narrow projection gives the database the opportunity to read and transmit less.

Star becomes more dangerous with joins

When multiple tables are involved, SELECT * can return duplicate column names, repeated identifiers, and fields the consumer cannot distinguish.

sql · avoid this join projection
-- Hard to consume and review.SELECT *FROM sale AS sJOIN customer AS c  ON c.customer_id = s.customer_id;
sql · prefer an explicit join contract
SELECT    s.sale_id       AS sale_id,    s.sold_at       AS sold_at,    c.customer_id   AS customer_id,    c.full_name     AS customer_name,    s.quantity      AS quantityFROM sale AS sJOIN customer AS c  ON c.customer_id = s.customer_id;

Joins are taught in Chapter 7; the important point here is that explicit output names prevent ambiguity.

When star is acceptable

ContextAssessment
Ad hoc exploration in a trusted local toolOften reasonable for quick inspection
Existence checkUsually unnecessary; select a literal or key instead
Production application queryPrefer explicit columns
Public API or exportUse a documented, versioned projection
View definitionPrefer explicit columns so view behavior is deliberate
Subquery used only internallyStill consider clarity and downstream needs

The rule is not “star is syntactically wrong.” The rule is “do not let source-schema accident define a durable interface.”

Lab: refactor an unstable query

Start with this broad query:

sqlite · original exploratory query
SELECT *FROM product AS p;

Assume the consumer needs a product catalogue with a stable public identifier, label, category, and price. Refactor it:

sqlite · explicit catalogue contract
SELECT    p.sku          AS product_code,    p.product_name AS product_name,    p.category     AS category,    p.unit_price   AS unit_priceFROM product AS p;

Now add a new internal column and verify that the explicit result shape does not change:

sqlite · evolution test
ALTER TABLE productADD COLUMN supplier_cost REAL;SELECT    p.sku          AS product_code,    p.product_name AS product_name,    p.category     AS category,    p.unit_price   AS unit_priceFROM product AS p;

Projection review checklist

Before approving a select list

  1. Does every output column serve a known consumer need?
  2. Could the result expose personal, confidential, or internal fields?
  3. Are output names unique and meaningful?
  4. Is the output order intentional?
  5. Will adding a source column unexpectedly change the result?
  6. Can the database avoid reading or transferring unused large values?
  7. Would a reviewer understand the result without opening the table definition?

Common mistakes

Using star to save typing

Typing is a one-time cost; unstable interfaces create recurring debugging and migration costs.

Assuming ORMs always protect the query

Generated SQL may still retrieve more than the projection requires. Inspect emitted queries and choose DTO or projection types deliberately.

Listing every column without purpose

An explicit list that blindly copies the entire table is more stable than star but may still expose and transfer unnecessary data.

Changing aliases casually

Output labels are part of a contract for many consumers. Rename them intentionally.

Summary and references

  • * delegates result shape to the source schema.
  • Explicit projections document purpose, order, and output names.
  • Narrow results reduce accidental exposure and may reduce work.
  • Star is useful for temporary exploration, not as a default production contract.
  • Join queries make explicit projection even more important.

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.