Chapter 04 · Reading Data with SELECT

SELECT, FROM, Aliases, and Query Result Sets

Begin reading relational data by controlling the source, projection, names, and interpretation of a query result.

Beginner65–85 minutesQuery foundations + SQLite labLast reviewed: August 2026

Learning outcomes

SELECT is SQL’s primary data-retrieval statement. It does not open a table and display it unchanged. It evaluates a query and returns a new result with its own columns, names, order, and values.

01

Explain the roles of SELECT, FROM, the select list, and a query result set.

02

Distinguish a stored table from the temporary result produced by a query.

03

Use table aliases, column aliases, and qualified column references clearly.

04

Create a reusable SQLite practice database and inspect several simple result sets.

The smallest useful retrieval query

sql · select named columns from one table
SELECT    customer_id,    full_name,    cityFROM customer;

The statement has two central parts:

S

SELECT

Defines the output expressions and therefore the columns of the result.

F

FROM

Defines the source relation or relations used to evaluate those expressions.

R

Result set

The rows and columns returned by this execution of the query.

;

Terminator

Marks the end of a statement in tools and scripts that accept multiple statements.

The comma-separated expressions after SELECT form the select list. In this example, every expression is a column reference.

A result is not the source table

A table is a persistent database object governed by a schema and constraints. A result set is produced when the DBMS evaluates a statement. It may expose fewer columns, rename them, repeat rows, compute new values, or combine multiple sources.

Stored tables
Query evaluation
Output expressions
Result set

The query reads from stored relations and constructs a separate output relation-like value for the client.

PropertyStored tableQuery result
LifetimePersists until changed or droppedUsually exists for the execution or client cursor
Column definitionDeclared by schemaDetermined by select-list expressions
ConstraintsMay have keys, checks, and foreign keysDoes not inherit table constraints as an enforceable schema
Row orderNo inherent presentation orderStill not guaranteed unless ORDER BY is used
Update behaviorMay support INSERT, UPDATE, DELETEUsually consumed as read output
No guaranteed row order yet

A plain SELECT may appear stable in a small database, but SQL does not promise presentation order without ORDER BY. Sorting is covered in Chapter 5.

Build the Chapter 4 practice database

Use a fresh SQLite database so every Chapter 4 example begins from the same small sales dataset.

sqlite · chapter 4 setup
PRAGMA foreign_keys = ON;DROP TABLE IF EXISTS sale;DROP TABLE IF EXISTS product;DROP TABLE IF EXISTS customer;CREATE TABLE customer (    customer_id  INTEGER PRIMARY KEY,    full_name    TEXT NOT NULL,    city         TEXT,    segment      TEXT NOT NULL                 CHECK (segment IN ('consumer', 'business'))) STRICT;CREATE TABLE product (    product_id   INTEGER PRIMARY KEY,    sku          TEXT NOT NULL UNIQUE,    product_name TEXT NOT NULL,    category     TEXT NOT NULL,    unit_price   REAL NOT NULL CHECK (unit_price >= 0)) STRICT;CREATE TABLE sale (    sale_id      INTEGER PRIMARY KEY,    customer_id  INTEGER NOT NULL                 REFERENCES customer(customer_id),    product_id   INTEGER NOT NULL                 REFERENCES product(product_id),    quantity     INTEGER NOT NULL CHECK (quantity > 0),    discount_rate REAL NOT NULL DEFAULT 0                  CHECK (discount_rate BETWEEN 0 AND 1),    sold_at      TEXT NOT NULL) STRICT;INSERT INTO customer    (customer_id, full_name, city, segment)VALUES    (1, 'Nadia Rahimi', 'Tehran', 'consumer'),    (2, 'Omar Haddad', 'Berlin', 'business'),    (3, 'Lina Chen', NULL, 'consumer'),    (4, 'Ava Morgan', 'Berlin', 'consumer');INSERT INTO product    (product_id, sku, product_name, category, unit_price)VALUES    (10, 'DB-101', 'Database Foundations', 'course', 49.00),    (11, 'SQL-201', 'SQL Query Practice', 'course', 69.00),    (12, 'REF-001', 'SQL Reference Card', 'book', 15.00),    (13, 'LAB-001', 'SQLite Lab Bundle', 'lab', 29.00);INSERT INTO sale    (sale_id, customer_id, product_id, quantity, discount_rate, sold_at)VALUES    (100, 1, 10, 1, 0.00, '2026-08-01 09:15:00'),    (101, 2, 11, 3, 0.10, '2026-08-01 10:45:00'),    (102, 1, 12, 2, 0.00, '2026-08-02 11:30:00'),    (103, 4, 10, 1, 0.15, '2026-08-03 13:05:00'),    (104, 2, 13, 2, 0.05, '2026-08-03 15:20:00'),    (105, 3, 12, 1, 0.00, '2026-08-04 08:00:00');

The schema has three tables: customers, products, and sales. Chapter 4 primarily reads those facts; later chapters will add filtering, joining, grouping, and changes.

Projection: choosing the output columns

In relational terminology, choosing attributes is called projection. SQL’s select list is more general than pure relational projection because it may contain expressions and may preserve duplicate rows, but the core idea is the same: control what the query returns.

sqlite · two different projections
SELECT customer_id, full_nameFROM customer;SELECT product_name, unit_priceFROM product;

The first result has two customer columns. The second has two product columns. Neither query changes the underlying tables.

Column aliases name the result

An alias changes the output label without renaming the stored column.

sqlite · explicit output aliases
SELECT    customer_id AS id,    full_name   AS customer_name,    city        AS customer_cityFROM customer;

AS is optional in many SQL dialects for column aliases, but writing it explicitly makes the intent visible and avoids confusion with missing commas.

Stored columnOutput labelStored schema changed?
customer_ididNo
full_namecustomer_nameNo
citycustomer_cityNo

Table aliases shorten and disambiguate references

A table alias gives a source a query-local name. It becomes particularly important when multiple tables contain columns such as customer_id or product_id.

sqlite · qualified column references
SELECT    c.customer_id,    c.full_name,    c.segmentFROM customer AS c;

Once customer AS c is declared, use c consistently in that query block. Qualification makes the origin of each column obvious and prepares the query for joins.

Alias scope

The alias exists only inside the statement or query block where it is declared. It does not rename the database table.

What the DBMS conceptually does

SQL is declarative: the query states the desired result rather than a row-by-row algorithm. A useful conceptual model for this simple query is:

Resolve FROM source
Read eligible source rows
Evaluate SELECT expressions
Return named result columns

The optimizer may execute physical operations differently, but the declarative meaning remains the same.

Do not treat the written order of clauses as a guarantee of physical execution. Query planning and optimization are introduced later in the course.

Lab: inspect basic result sets

sqlite · run and compare
-- Result 1: customer identity and labels.SELECT    c.customer_id AS customer_id,    c.full_name   AS customer_name,    c.city        AS cityFROM customer AS c;-- Result 2: product catalogue projection.SELECT    p.sku          AS sku,    p.product_name AS product_name,    p.unit_price   AS unit_priceFROM product AS p;-- Result 3: raw sale facts.SELECT    s.sale_id,    s.customer_id,    s.product_id,    s.quantity,    s.sold_atFROM sale AS s;

Compare the number of source columns with the number returned by each statement. Notice that an alias changes only the result header.

Common mistakes

Assuming output order

The database may return rows in any order unless a later ORDER BY clause defines it.

Using ambiguous names

As queries grow, unqualified columns can become unclear or invalid. Use meaningful table aliases.

Confusing aliases with schema changes

An alias is temporary output metadata, not a rename operation.

Thinking SELECT means all columns

SELECT introduces an output list. The author must decide what belongs in that list.

Checkpoint

Reason about the query

  1. Which clause identifies the source table?
  2. Which part determines the number and names of output columns?
  3. Does AS customer_name rename the stored full_name column?
  4. Can a plain SELECT promise that customer_id 1 appears before customer_id 2?
  5. Why might c.customer_id be clearer than customer_id?
Review the answers

FROM identifies the source. The select list defines output expressions and labels. Aliases do not alter schema. Row order is not guaranteed without ORDER BY. Qualification identifies the source and avoids ambiguity.

Summary and references

  • FROM identifies source relations.
  • The select list defines the result columns.
  • A query result is separate from its source table.
  • Column aliases label output; table aliases label sources.
  • Qualified names improve clarity and become essential in multi-table queries.

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.