The smallest query
select says which columns come back. from says where the rows come from. Everything else in this course is a clause added to those two.
select * from doors; -- every column of every row
select name from doors; -- one column of every row
select 2 + 2; -- no table at all: 4
Never ship select *
select * is for looking around. In an application it is a slow way to fetch data you do not use, and a silent bug waiting for the day someone adds a column: your code suddenly receives a field it has never seen, and the row got twice as big on the wire.
Name the columns. The query then says what the code needs, and a reader can tell at a glance.
select name, style, price
from doors;
Aliases: as
select name as door,
lead_days as days_to_make,
price * 1.18 as with_vat
from doors;
-- as is optional, but leaving it out reads like a typo
select name door from doors;
-- a name with a space or a capital needs double quotes
select price as "Price, incl. VAT" from doors;
In SQL, 'text' is a string and "text" is an identifier — a column or table name. select 'name' from doors returns the word "name" ten times, once per row. MySQL is loose about this; everything else is not.
Columns you compute
A select expression is worked out once per row. case is SQL's if: a list of conditions, the first true one wins, else catches the rest.
select name,
price,
price * 1.18 as with_vat,
round(price * 1.18, 2) as tidy,
name || ' (' || style || ')' as label, -- || joins text
upper(material) as material,
case when price > 2000 then 'premium' else 'standard' end as tier
from doors;
|| is the standard and works in SQLite, PostgreSQL and Oracle. MySQL uses concat(a, b) — and reads || as "or" unless it is told otherwise.
distinct
distinct applies to the whole row that comes back, not to one column — which is why the second query returns more rows than the first, not the same rows with an extra column.
select distinct style from doors; -- 4 rows
select distinct style, material from doors; -- every pair that exists
Comments, case and layout
Keywords are conventionally written one way and kept consistent — lower case reads better in an application file, upper case in a migration; pick one. Table and column names are case-insensitive in most databases, but a quoted identifier is not, which is a good reason never to quote them.
-- a line comment
/* a block comment,
which is useful for switching a clause off */
select name, -- keywords in one case, your names in another
price
from doors; -- keyword case is free; SQL is not case sensitive here