Based on Relational Algebra
SQL is more readable than Relational Algebra.
SPJ Query
Select-Project-Join (SPJ) query. Is what almost all queries are. in the form of:
…is equivalent to…
⇒ Think: you are checking {postgresql} condition
on the whole cross product of relation1, relation2, …
Canonical form of a single query
Joins, Unions and Differences
- table references scoping is like other languages
- subtables can be one tuple & one column (=scalar), where you can do a direct comparison:
{postgresql}WHERE age [>=<] (subtable)
- …but this will cause runtime error if the subtable has more than one value.
{postgresql}SELECT DISTINCT
to remove duplicates{postgresql}EXCEPT/INTERSECT/UNION ALL
is a bag operation that removes by count; Example data
Conditionals
Null Handling Rules.
NULL
andUnknown
as a 0.5 value
- Comparing
NULL
with any value will result inUNKNOWN
- Values as numbers:
TRUE
False
UNKNOWN
- Operations as functions:
{postgresql}x AND y
{postgresql}x OR y
{postgresql}NOT x
What about handling null results?
- Solution 1:
{postgresql}SELECT COALESCE(col,0.0)
- ⇒ if
{postgresql}col = NULL
, will return0.0
- ⇒ if
- Solution 2:
{postgresql}SELECT NULLIF(col,'n/a')
- ⇒ if
{postgresql}col = 'n/a'
, will returnNULL
- ⇒ if
SQL Extensions
Aggregation
- An aggregation in a HAVING clause applies only to the tuples of the group being tested.
- Any attribute of relations in the FROM clause may be aggregated in the HAVING clause, but only those attributes that are in the GROUP BY list may appear unaggregated in the HAVING clause (the same rule as for the SELECT clause).
Grouping
- Compute Order:
{postgresql}GROUP BY
- `{postgresql}HAVING
{postgresql}SELECT
aggr_func
is computed for each group- e.g.
{postgreSQL}SELECT age, AVG(pop) FROM User GROUP BY age
computes the average popularity for each age. - e.g.
{postgresql} SELECT uid, MAX(pop) FROM User
is wrong ← aggregate function and column cannot be used together (whichuid
?) - e.g.
{postgresql}SELECT uid, age FROM User GROUP BY age
is wrong ← whichuid
? “
- e.g.
Variables
Two forms of “variables”
- Named Subqueries (will evaluate by macro expansion)
- Views (is a window into a table)
- Provides Logical data independence
Data Input/Output
Advanced Topics
- Transaction
- Allows multiple queries to be treated as one (helps when making new tables with foreign key relations)
- Object-Relational Mapping
- Convert between object-oriented language’s object data into SQL-compatible tuples, and vice versa
- Casting
- Convert between datatypes
{postgresql}CAST(num AS FLOAT)
- Convert between datatypes
Recursion
- You can define new subtables with recursion
{postgresql}WITH RECURSIVE subtable AS (recursive_query)
- SQL does fixed point recursion
- …i.e. recurses until the table doesn’t seem to change anymore
- Linear vs Non-linear recursion
- Linear: a single recursive call
- Non-linear: a tree-like recursion; multiple recursive calls
- Mutual Recursion
- Two tables are defined upon each other