Data Engineering
SQL
1
SQL: Structured Query Language (or “sequel”)
2
The Basic Form: Select From Where
Basic Form:
SELECT attributes
FROM tables
WHERE condition about tuples in tables
If you’re trying to map this to RA, beware that SELECT is projection, and WHERE is selection!
Let’s start with some single table examples…
3
Basic Examples
SELECT * FROM Stops
id | race | gender | age | warning | citation | arrest |
17213 | asian | F | 23 | False | True | False |
1 | white | M | 45 | True | False | False |
2 | black | M | 37 | False | False | False |
19 | hispanic | F | 58 | False | True | False |
id | race | gender | age | warning | citation | arrest |
17213 | asian | F | 23 | False | True | False |
1 | white | M | 45 | True | False | False |
2 | black | M | 37 | False | False | False |
19 | hispanic | F | 58 | False | True | False |
Basic Examples
SELECT gender, citation
FROM Stops
Duplicates are preserved!
id | race | gender | age | warning | citation | arrest |
17213 | asian | F | 23 | False | True | False |
1 | white | M | 45 | True | False | False |
2 | black | M | 37 | False | False | False |
19 | hispanic | F | 58 | False | True | False |
gender | citation |
F | True |
M | False |
M | False |
F | True |
Basic Examples
SELECT gender, citation
FROM Stops
WHERE citation = True
id | race | gender | age | warning | citation | arrest |
17213 | asian | F | 23 | False | True | False |
1 | white | M | 45 | True | False | False |
2 | black | M | 37 | False | False | False |
19 | hispanic | F | 58 | False | True | False |
gender | citation |
F | True |
F | True |
Basic Examples
SELECT DISTINCT gender, citation
FROM Stops
WHERE citation = True
id | race | gender | age | warning | citation | arrest |
17213 | asian | F | 23 | False | True | False |
1 | white | M | 45 | True | False | False |
2 | black | M | 37 | False | False | False |
19 | hispanic | F | 58 | False | True | False |
gender | citation |
F | True |
Basic Examples
SELECT * FROM Stops
WHERE gender != “M” AND age > 30
id | race | gender | age | warning | citation | arrest |
17213 | asian | F | 23 | False | True | False |
1 | white | M | 45 | True | False | False |
2 | black | M | 37 | False | False | False |
19 | hispanic | F | 58 | False | True | False |
id | race | gender | age | warning | citation | arrest |
19 | hispanic | F | 58 | False | True | False |
Null Values
9
Multi-relation Queries
10
id | race | location | age | warning | citation | arrest |
17213 | asian | MacArthur | 23 | False | True | False |
1 | white | West Oakland | 45 | True | False | False |
2 | black | West Oakland | 37 | False | False | False |
19 | hispanic | Civic Center | 58 | False | True | False |
location | zipcode |
MacArthur | 94621 |
West Oakland | 94609 |
Civic Center | 94612 |
id | race | Stops.location | age | warning | citation | arrest | Zips.location | zipcode |
17213 | asian | MacArthur | 23 | False | True | False | MacArthur | 94621 |
1 | white | West Oakland | 45 | True | False | False | West Oakland | 94609 |
2 | black | West Oakland | 37 | False | False | False | West Oakland | 94609 |
19 | hispanic | Civic Center | 58 | False | True | False | Civic Center | 94612 |
Multi-relation Queries
11
id | race | location | age | warning | citation | arrest |
17213 | asian | MacArthur | 23 | False | True | False |
1 | white | West Oakland | 45 | True | False | False |
2 | black | West Oakland | 37 | False | False | False |
19 | hispanic | Civic Center | 58 | False | True | False |
location | zipcode |
MacArthur | 94621 |
West Oakland | 94609 |
Civic Center | 94612 |
SELECT * FROM Stops, Zips WHERE Stops.location = Zips.location
SELECT * FROM Stops AS S, Zips AS Z WHERE S.location = Z.location
SELECT race, zipcode FROM Stops AS S, Zips AS Z WHERE S.location = Z.location // only keep race and zipcode
How to Read a SQL Query w/ Mult. Tables
12
New Demo Dataset: IMDB
Real subset of the IMDB dataset!
Example
14
Step 1: What tables does the DB have?
Schema | Name | Type | Owner
--------+----------+-------+-------------
public | akas | table | lakshyajain
public | crew | table | lakshyajain
public | episodes | table | lakshyajain
public | people | table | lakshyajain
public | ratings | table | lakshyajain
public | titles | table | lakshyajain
If we want to get the movies Morgan Freeman has acted in, what tables should we use?
We can’t tell from this alone! We have a good heuristic from names -- the tables of interest are probably titles, people, and crew, at the least. But we need to investigate further
Step 2: What are the schemas of the tables?
imdb=# \d titles
Table "public.titles"
Column | Type | Collation | Nullable | Default
-----------------+-------------------+-----------+----------+---------
title_id | character varying | | not null |
type | character varying | | |
primary_title | character varying | | |
original_title | character varying | | |
is_adult | integer | | |
premiered | integer | | |
ended | integer | | |
runtime_minutes | integer | | |
genres | character varying | | |
Indexes:
"titles_pkey" PRIMARY KEY, btree (title_id)
Schemas cont’d
imdb=# \d crew
Table "public.crew"
Column | Type | Collation | Nullable | Default
-----------+-------------------+-----------+----------+---------
title_id | character varying | | |
person_id | character varying | | |
category | character varying | | |
job | character varying | | |
Schemas cont’d
imdb=# \d people
Table "public.people"
Column | Type | Collation | Nullable | Default
-----------+-------------------+-----------+----------+---------
person_id | character varying | | not null |
name | character varying | | |
born | integer | | |
died | integer | | |
Indexes:
"people_pkey" PRIMARY KEY, btree (person_id)
What do we do?
Query time!
on crew.title_id = titles.title_id��inner join people
on people.person_id = crew.person_id
What do we want?
ON crew.title_id = titles.title_id��INNER JOIN people
ON people.person_id = crew.person_id
Query 1: All Morgan Freeman movies
OK, what do I do with the result of a query?
Many things; you can define/create
Option 1: Create a New Table
CREATE TABLE CitationStops AS
(SELECT gender, citation
FROM Stops
WHERE citation = True)
Treated as a regular table after invocation
If base table changes, we must manually change any derived tables
Option 2: Create a Virtual View (View for short)
CREATE VIEW CitationStops AS
(SELECT gender, citation
FROM Stops
WHERE citation = True)
Output is not stored; computed on demand as part of the query
Think of this as a variable or as a virtual relation that is more convenient to query than the base table
e.g., refer as usual: SELECT * FROM CitationStops
Sometimes defined for access control – more on that later
Option 3: Create an Inlined View: Common Table Expression
WITH CitationStops AS
(SELECT gender, citation
FROM Stops
WHERE citation = True)
SELECT * FROM CitationStops
Like virtual views, CTEs are computed on demand
Option 4: Create a Materialized View
CREATE MATERIALIZED VIEW CitationStops AS
(SELECT gender, citation
FROM Stops
WHERE citation = True)
Output is stored on the disk, just like a regular table, and unlike views
Key benefit over regular tables: MVs automatically updated as base table(s) change
However, many MVs can add unnecessary overhead to any base table updates
So…let’s cache our table.
Query 2: RATINGS
Query 2: RATINGS
title_id | rating | votes | primary_title
-----------+--------+---------+-------------------------------
tt0111161 | 9.3 | 2128705 | The Shawshank Redemption
tt0105695 | 8.2 | 345874 | Unforgiven
tt1256638 | 8.7 | 9 | Where the Water Meets the Sky
Translation to Relational Algebra
31
Translation to Relational Algebra
32
Recap
33
Queries
34