SELECT, FROM & Columns
Overview
Every SQL query is a row-set transformation: you start with a set of rows and transform it into a new set. SELECT and FROM are the two minimum clauses that make a valid query. FROM names the source table — the initial row-set. The database loads every row of that table into a working set. SELECT names which columns to keep (or compute) in the output. Think of FROM as 'which filing cabinet?' and SELECT as 'which columns from each sheet?' SELECT * returns all columns: SELECT * FROM customers; Returns all 8 rows with columns id, name, country, signup_date. SELECT with specific columns narrows the output: SELECT name, country FROM customers ORDER BY id; Returns 8 rows but only the name and country columns. You can also create computed columns with expressions and aliases using AS: SELECT name, price, price * 1.1 AS price_with_tax FROM products ORDER BY id; Returns 6 rows, each with the original price and a computed price_with_tax column. Key mental model: in the logical query flow, FROM runs first (builds the full row-set), then SELECT runs (picks/computes columns). Even though you write SELECT first in the text, the database processes FROM first.
SELECT and FROM are the foundation of every SQL statement. You cannot write any query — filtering, joining, aggregating — without them. Understanding that FROM runs before SELECT prevents the #1 beginner mistake: trying to use a SELECT alias in the same SELECT list or in a WHERE clause.
Where used: every SQL query ever written, API list endpoints, data exploration in psql or pgAdmin
Why learn this
- Every other SQL concept (WHERE, JOIN, GROUP BY) builds on SELECT + FROM — they are the skeleton of every query
- Understanding column aliases (AS) is required for readable output in API responses and reports
Query walkthrough
SELECT name, price, price * 1.1 AS price_with_tax
FROM products
ORDER BY name;
Focus: Watch how FROM loads all 6 product rows, then SELECT keeps only name and price and computes a new column price_with_tax from an expression.
Common mistakes
- Using SELECT * in production queries: SELECT * pulls every column, including ones you don't need. It breaks if the table schema changes (new columns appear unexpectedly). Always list the columns you want explicitly.
- Thinking SELECT runs before FROM: You write SELECT first, but the database processes FROM first to build the row-set, then SELECT to pick columns. This is why you cannot reference a SELECT alias in a WHERE clause in the same query.
- Forgetting AS for computed columns: Without an alias, a computed expression like price * 1.1 gets an auto-generated column name that varies by database. Always use AS to give it a clear name: price * 1.1 AS price_with_tax.
Glossary
- transformation
- The process of taking an initial set of data and changing or shaping it into a new output.
- skeleton
- The basic, underlying structure of a query that everything else is built upon.
- explicitly
- Stating something clearly and directly, leaving no room for confusion or guessing.
Recall questions
- In the logical query flow, which clause does the database process first — SELECT or FROM?
- What does SELECT * return compared to SELECT name, country?
- What does the AS keyword do in a SELECT clause?
Understanding checks
What rows and columns does this query return?
One row: name = 'Notebook', double_price = 9.98.
FROM loads all 6 products, WHERE keeps only Stationery (Notebook, price 4.99), then SELECT computes the two output columns: name and 4.99 * 2 = 9.98.
How many rows come back, and what appears in the country column for every row?
8 rows. The country values in order are: US, US, MX, UK, NULL, AE, US, JP.
FROM loads all 8 customers, SELECT keeps only the country column. Emma (id 5) has NULL country, which appears as NULL in the output — SELECT does not skip NULLs.
Practice tasks
Add a computed discount column
This query shows product names and prices. Modify it to also include a column called discounted_price that shows each price reduced by 10% (price * 0.9). Keep the existing columns and ordering.
Challenge
Customer signup roster
Write a query that returns only the name and signup_date columns from the customers table, ordered by signup_date (earliest first).
Continue learning
Next: WHERE & Operators
Next: INNER JOIN