Chapter 04 · Reading Data with SELECT

Expressions, Literals, and Computed Columns

Transform stored values into query-time information while preserving types, NULL behavior, and readable output names.

Beginner75–95 minutesExpression semantics + SQLite labLast reviewed: August 2026

Learning outcomes

A select-list item can be more than a stored column. SQL expressions combine columns, literals, operators, and functions to derive values at query time. These values are returned in the result but are not written back to the table.

01

Identify numeric, text, NULL, date-time, and identifier literals in SQL.

02

Build arithmetic and text expressions from stored columns.

03

Use aliases to give computed columns stable, meaningful names.

04

Reason about type conversion, integer versus real arithmetic, and NULL propagation.

Expressions produce one value per result row

sqlite · arithmetic computed column
SELECT    s.sale_id,    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;

For each matched sale row, the DBMS evaluates s.quantity * p.unit_price. The alias gross_amount labels that output expression.

Input row values
Evaluate expression
Assign output alias
Return computed value

A computed column exists in the query result unless it is explicitly stored by another statement or schema feature.

Literal values

A literal represents a value written directly in the statement.

Literal familyExamplesNotes
Integer0, 42, -7Exact whole-number syntax
Real numeric3.14, 1.0May be approximate depending on engine/type
Text'consumer', 'SQL'Single quotes delimit SQL strings
NULLNULLRepresents missing or inapplicable information
Date/time text in SQLite'2026-08-05'SQLite commonly stores ISO-style text, integer, or real time values
Blob in SQLiteX'53514C'Hexadecimal byte sequence
sqlite · literal-only result
SELECT    42                  AS integer_value,    3.14                AS real_value,    'SQL'               AS text_value,    NULL                AS missing_value,    '2026-08-05'        AS date_text,    X'53514C'           AS blob_value;

Single quotes and identifiers are different

Single quotes delimit string literals. Identifier quoting differs by dialect; standard SQL uses double quotes for delimited identifiers. Avoid creating identifiers that require quoting unless there is a strong reason.

sql · value versus identifier
SELECT    'product_name' AS literal_text,    product_name   AS column_valueFROM product;

The first expression returns the same text for every row. The second reads the column value.

Do not use quotes interchangeably

Some engines accept nonstandard quoting for compatibility, but portable SQL should use single quotes for strings and unquoted, simple names for ordinary identifiers.

Arithmetic expressions

sqlite · sale calculations
SELECT    s.sale_id,    s.quantity,    p.unit_price,    s.discount_rate,    s.quantity * p.unit_price AS gross_amount,    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;

Parentheses communicate grouping and protect the intended evaluation order. Chapter 5 studies operator precedence more directly.

OperatorTypical meaning
+Addition
-Subtraction or unary negation
*Multiplication
/Division; result type and zero behavior vary by engine and operand types
%Remainder in engines that support it

Integer and real arithmetic

Type behavior matters. In SQLite, the values participating in an operation influence the result.

sqlite · compare division forms
SELECT    5 / 2       AS integer_division,    5.0 / 2     AS real_division,    CAST(5 AS REAL) / 2 AS cast_division;

In SQLite, 5 / 2 produces integer division because both operands are integers, while introducing a real operand yields a real result. Other engines have their own numeric type rules, so use deliberate types and test boundary cases.

Text concatenation

SQLite and PostgreSQL use || for concatenation. SQL Server commonly uses +, while MySQL commonly uses CONCAT() unless configured otherwise.

sqlite · computed display label
SELECT    p.sku,    p.sku || ' — ' || p.product_name AS product_labelFROM product AS p;

Computed display labels are useful, but avoid mixing presentation concerns into every query if the application already has a consistent formatting layer.

NULL propagates through many expressions

sqlite · NULL expression behavior
SELECT    c.customer_id,    c.full_name,    c.city,    c.city || ', customer' AS city_labelFROM customer AS c;

For Lina Chen, city is NULL, so concatenation also returns NULL. Chapter 6 introduces COALESCE and related tools for deliberate fallback behavior.

Unknown input, unknown result

Many operators return NULL when an operand is NULL. Do not silently replace missing values until the business meaning of the replacement is clear.

Aliases for computed columns

Without an alias, clients may receive an engine-generated expression label such as quantity * unit_price. That label is awkward and unstable.

sqlite · stable computed output contract
SELECT    s.sale_id AS sale_id,    s.quantity * p.unit_price AS gross_amount,    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;

Choose names that describe the value and, when needed, its unit or basis: net_amount, duration_seconds, price_usd, or temperature_celsius.

Lab: produce a sale-line report

sqlite · computed report columns
SELECT    s.sale_id,    s.sold_at,    p.sku,    p.product_name,    s.quantity,    p.unit_price,    s.discount_rate * 100 AS discount_percent,    s.quantity * p.unit_price AS gross_amount,    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;

Verify the calculations manually for at least one row. Query output is not trustworthy merely because the SQL executed successfully.

Type inspection in SQLite

sqlite · inspect runtime storage classes
SELECT    typeof(42)                  AS integer_type,    typeof(3.14)                AS real_type,    typeof('SQL')               AS text_type,    typeof(NULL)                AS null_type,    typeof(X'53514C')           AS blob_type,    typeof(5 / 2)               AS division_type,    typeof(CAST(5 AS REAL) / 2) AS cast_division_type;

typeof() is SQLite-specific and useful for learning. Portable schemas and applications should rely on documented column and expression types rather than engine-specific inspection alone.

Common mistakes

Forgetting an alias

Unnamed computed columns create unclear client contracts.

Assuming arithmetic types

Integer division, decimal precision, overflow, and implicit conversion differ across engines.

Using double quotes for text

Double quotes are for delimited identifiers in standard SQL. Use single quotes for string literals.

Ignoring NULL

A correct formula over known values may return NULL when any required input is missing.

Embedding units only in prose

When ambiguity is possible, encode the unit in the alias or data model.

Summary and references

  • Select-list expressions are evaluated for result rows.
  • Literals represent values written directly in SQL.
  • Aliases give computed columns stable names.
  • Numeric result types depend on operand types and engine rules.
  • NULL commonly propagates through arithmetic and concatenation.

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.