Skip to content

Commit

Permalink
Merge branch 'main' of github.com:gvwilson/sql-tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
gvwilson committed Feb 6, 2024
2 parents 1481ed0 + ace4f26 commit 1b6584f
Show file tree
Hide file tree
Showing 38 changed files with 200 additions and 177 deletions.
44 changes: 24 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include misc/tutorial.mk
include depend.mk

SQLITE := sqlite3
DB := db
Expand All @@ -19,7 +20,9 @@ EXCLUDED_SQL := \
${SRC}/make_active.sql \
${SRC}/create_work_job.sql \
${SRC}/lineage_setup.sql \
${SRC}/trigger_setup.sql
${SRC}/populate_work_job.sql \
${SRC}/trigger_setup.sql \
${SRC}/update_work_job.sql
OUT_FILES := \
$(patsubst ${SRC}/%.sql,${OUT}/%.out,$(filter-out ${EXCLUDED_SQL},${SQL_FILES})) \
$(patsubst ${SRC}/%.py,${OUT}/%.out,${PY_FILES})
Expand Down Expand Up @@ -51,6 +54,10 @@ ${DB}/penguins.db : bin/create_penguins_db.sql misc/penguins.csv
release:
zip -r sql-tutorial.zip db src out -x \*~

## depend.mk: rebuild SQL-to-SQL dependencies
depend.mk:
@python bin/make_depend.py ${SQL_FILES} > $@

## lint: check project state
.PHONY: lint
lint:
Expand Down Expand Up @@ -81,17 +88,17 @@ freq:
.PHONY: run
run: ${OUT_FILES}

${OUT}/active_penguins.out: ${SRC}/active_penguins.sql ${SRC}/make_active.sql
${OUT}/active_penguins.out: ${SRC}/active_penguins.sql
cp ${DB}/penguins.db /tmp
cat ${MODE} $< | ${PENGUINS_TMP} > $@

${OUT}/admin_commands.out: ${SRC}/admin_commands.sql
cat $< | ${PENGUINS} > $@

${OUT}/aggregate_join.out: ${SRC}/aggregate_join.sql ${SRC}/create_work_job.sql
${OUT}/aggregate_join.out: ${SRC}/aggregate_join.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/aggregate_left_join.out: ${SRC}/aggregate_left_join.sql ${SRC}/create_work_job.sql
${OUT}/aggregate_left_join.out: ${SRC}/aggregate_left_join.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/all_jobs.out: ${SRC}/all_jobs.sql
Expand All @@ -115,7 +122,7 @@ ${OUT}/autoincrement.out: ${SRC}/autoincrement.sql
${OUT}/avoid_correlated_subqueries.out: ${SRC}/avoid_correlated_subqueries.sql
cat ${MODE} $< | ${ASSAYS} > $@

${OUT}/backing_up.out: ${SRC}/backing_up.sql ${SRC}/create_work_job.sql
${OUT}/backing_up.out: ${SRC}/backing_up.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/basic_python_query.out: ${SRC}/basic_python_query.py
Expand All @@ -137,7 +144,7 @@ ${OUT}/case_when.out: ${SRC}/case_when.sql
${OUT}/check_range.out: ${SRC}/check_range.sql
cat ${MODE} $< | ${PENGUINS} > $@

${OUT}/coalesce.out: ${SRC}/coalesce.sql ${SRC}/create_work_job.sql
${OUT}/coalesce.out: ${SRC}/coalesce.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/common_aggregations.out: ${SRC}/common_aggregations.sql
Expand Down Expand Up @@ -171,7 +178,7 @@ ${OUT}/create_use_index.out: ${SRC}/create_use_index.sql
cp ${DB}/assays.db /tmp
cat ${MODE} $< | ${ASSAYS_TMP} > $@

${OUT}/cross_join.out: ${SRC}/cross_join.sql ${SRC}/create_work_job.sql
${OUT}/cross_join.out: ${SRC}/cross_join.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/data_range_sequence.out: ${SRC}/data_range_sequence.sql
Expand All @@ -183,7 +190,7 @@ ${OUT}/date_sequence.out: ${SRC}/date_sequence.sql
${OUT}/dates_times.out: ${SRC}/dates_times.py
python $< > $@

${OUT}/delete_rows.out: ${SRC}/delete_rows.sql ${SRC}/create_work_job.sql
${OUT}/delete_rows.out: ${SRC}/delete_rows.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/distinct.out: ${SRC}/distinct.sql
Expand Down Expand Up @@ -234,7 +241,7 @@ ${OUT}/if_else.out: ${SRC}/if_else.sql
${OUT}/incremental_fetch.out: ${SRC}/incremental_fetch.py
python $< > $@

${OUT}/inner_join.out: ${SRC}/inner_join.sql ${SRC}/create_work_job.sql
${OUT}/inner_join.out: ${SRC}/inner_join.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/insert_delete.out: ${SRC}/insert_delete.py
Expand All @@ -243,7 +250,7 @@ ${OUT}/insert_delete.out: ${SRC}/insert_delete.py
${OUT}/insert_select.out: ${SRC}/insert_select.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/insert_values.out: ${SRC}/insert_values.sql ${SRC}/create_work_job.sql
${OUT}/insert_values.out: ${SRC}/insert_values.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/interpolate.out: ${SRC}/interpolate.py
Expand Down Expand Up @@ -276,7 +283,7 @@ ${OUT}/lab_log_schema.out: ${SRC}/lab_log_schema.sql
${OUT}/lead_lag.out: ${SRC}/lead_lag.sql
cat ${MODE} $< | ${ASSAYS} > $@

${OUT}/left_join.out: ${SRC}/left_join.sql ${SRC}/create_work_job.sql
${OUT}/left_join.out: ${SRC}/left_join.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/like_glob.out: ${SRC}/like_glob.sql
Expand All @@ -285,7 +292,7 @@ ${OUT}/like_glob.out: ${SRC}/like_glob.sql
${OUT}/limit.out: ${SRC}/limit.sql
cat ${MODE} $< | ${PENGUINS} > $@

${OUT}/negate_incorrectly.out: ${SRC}/negate_incorrectly.sql ${SRC}/create_work_job.sql
${OUT}/negate_incorrectly.out: ${SRC}/negate_incorrectly.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/nonexistence.out: ${SRC}/nonexistence.sql
Expand Down Expand Up @@ -360,15 +367,12 @@ ${OUT}/self_join.out: ${SRC}/self_join.sql
${OUT}/sequence_table.out: ${SRC}/sequence_table.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/set_membership.out: ${SRC}/set_membership.sql ${SRC}/create_work_job.sql
${OUT}/set_membership.out: ${SRC}/set_membership.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/show_missing_values.out: ${SRC}/show_missing_values.sql
cat ${MODE} $< | ${PENGUINS} > $@

${OUT}/show_work_job.out: ${SRC}/show_work_job.sql ${SRC}/create_work_job.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/simple_group.out: ${SRC}/simple_group.sql
cat ${MODE} $< | ${PENGUINS} > $@

Expand All @@ -381,7 +385,7 @@ ${OUT}/sort.out: ${SRC}/sort.sql
${OUT}/specify_columns.out: ${SRC}/specify_columns.sql
cat ${MODE} $< | ${PENGUINS} > $@

${OUT}/subquery_set.out: ${SRC}/subquery_set.sql ${SRC}/create_work_job.sql
${OUT}/subquery_set.out: ${SRC}/subquery_set.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/ternary_logic.out: ${SRC}/ternary_logic.sql
Expand All @@ -390,10 +394,10 @@ ${OUT}/ternary_logic.out: ${SRC}/ternary_logic.sql
${OUT}/transaction.out: ${SRC}/transaction.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/trigger_firing.out: ${SRC}/trigger_firing.sql ${SRC}/trigger_setup.sql
${OUT}/trigger_firing.out: ${SRC}/trigger_firing.sql
-cat ${MODE} $< | ${MEMORY} >& $@

${OUT}/trigger_successful.out: ${SRC}/trigger_successful.sql ${SRC}/trigger_setup.sql
${OUT}/trigger_successful.out: ${SRC}/trigger_successful.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/unaggregated_columns.out: ${SRC}/unaggregated_columns.sql
Expand All @@ -409,7 +413,7 @@ ${OUT}/update_group_ids.out: ${SRC}/update_group_ids.sql
cp ${DB}/contact_tracing.db /tmp
cat ${MODE} $< | ${CONTACTS_TMP} > $@

${OUT}/update_rows.out: ${SRC}/update_rows.sql ${SRC}/create_work_job.sql
${OUT}/update_rows.out: ${SRC}/update_rows.sql
cat ${MODE} $< | ${MEMORY} > $@

${OUT}/upsert.out: ${SRC}/upsert.sql
Expand Down
18 changes: 12 additions & 6 deletions _data/glossary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@
# C

- key: cross_join
en:
term: cross join
def: >
A join that creates the cross-product of rows from two tables.
- key: cte
en:
term: common table expression
Expand Down Expand Up @@ -154,6 +160,12 @@
def: >
A value in one table that identifies a primary key in another table.
- key: full_outer_join
en:
term: full outer join
def: >
See <a href="#g:cross_join">cross join</a>.
# G

- key: group
Expand Down Expand Up @@ -268,12 +280,6 @@
A library that translates objects in a program into database queries
and the results of those queries back into objects.
- key: outer_join
en:
term: outer join
def: >
A join that creates the cross-product of rows from two tables.
# P

- key: path_expression
Expand Down
19 changes: 19 additions & 0 deletions bin/make_depend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Regenerate SQL dependency description for Make."""

from pathlib import Path
import sys


def main():
"""Main driver."""
for src in sys.argv[1:]:
lines = [ln.replace(".read", "").strip() for ln in Path(src).read_text().split("\n") if ln.startswith(".read")]
if not lines:
continue
src = src.replace("src/", "${OUT}/").replace(".sql", ".out")
lines = [ln.replace("src/", "${SRC}/") for ln in lines]
print(f"{src}: {' '.join(lines)}")


if __name__ == "__main__":
main()
19 changes: 19 additions & 0 deletions depend.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
${OUT}/active_penguins.out: ${SRC}/make_active.sql
${OUT}/aggregate_join.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/aggregate_left_join.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/backing_up.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql ${SRC}/update_work_job.sql
${OUT}/coalesce.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/cross_join.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/delete_rows.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql ${SRC}/update_work_job.sql
${OUT}/inner_join.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/insert_values.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/left_join.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/negate_incorrectly.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/recursive_lineage.out: ${SRC}/lineage_setup.sql
${OUT}/represent_graph.out: ${SRC}/lineage_setup.sql
${OUT}/set_membership.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/subquery_set.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql
${OUT}/trigger_firing.out: ${SRC}/trigger_setup.sql
${OUT}/trigger_successful.out: ${SRC}/trigger_setup.sql
${OUT}/update_rows.out: ${SRC}/create_work_job.sql ${SRC}/populate_work_job.sql ${SRC}/update_work_job.sql
${OUT}/views.out: ${SRC}/make_active.sql
4 changes: 4 additions & 0 deletions img/concept_map_join.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 12 additions & 4 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,6 @@ home: true
{% include h2_numbered.md title="create tables" %}

{% include single.md file="src/create_work_job.sql" %}
{% include single.md file="out/show_work_job.out" %}

- <code>create table <em>name</em></code> followed by parenthesized list of columns
- Each column is a name, a data type, and optional extra information
Expand All @@ -447,14 +446,16 @@ home: true

{% include h2_numbered.md title="insert data" %}

{% include double.md stem="insert_values" suffix="sql out" %}
{% include single.md file="src/populate_work_job.sql" %}
{% include single.md file="out/insert_values.out" %}

</section>
<section markdown="1">

{% include h2_numbered.md title="update rows" %}

{% include double.md stem="update_rows" suffix="sql out" %}
{% include single.md file="src/update_work_job.sql" %}
{% include single.md file="out/update_rows.out" %}

- (Almost) always specify row(w) to update using `where`
- Would otherwise update all rows
Expand Down Expand Up @@ -492,7 +493,7 @@ home: true
{% include double.md stem="cross_join" suffix="sql out" %}

- A <a href="#g:join">join</a> combines information from two tables
- `cross join` (also called <a href="#g:outer_join">outer join</a>) constructs their cross product
- <a href="#g:full_outer_join">full outer join</a> (also called <a href="#g:cross_join">cross join</a>) constructs their cross product
- All combinations of rows from each
- Result isn't particularly useful: `job` and `name` don't match

Expand Down Expand Up @@ -540,6 +541,13 @@ home: true
</section>
<section markdown="1">

{% include h2_unnumbered.md title="check your understanding" %}

![concept map: join](./img/concept_map_join.svg)

</section>
<section markdown="1">

{% include h2_numbered.md title="coalesce values" %}

{% include double.md stem="coalesce" suffix="sql out" %}
Expand Down
12 changes: 4 additions & 8 deletions out/aggregate_join.out
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
CREATE TABLE job (
name text not null,
billable real not null
);
CREATE TABLE work (
person text not null,
job text not null
);
| person | pay |
|--------|-----|
| mik | 2.0 |
| po | 0.5 |
13 changes: 5 additions & 8 deletions out/aggregate_left_join.out
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
CREATE TABLE job (
name text not null,
billable real not null
);
CREATE TABLE work (
person text not null,
job text not null
);
| person | pay |
|--------|-----|
| mik | 2.0 |
| po | 0.5 |
| tay | |
11 changes: 3 additions & 8 deletions out/backing_up.out
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
CREATE TABLE job (
name text not null,
billable real not null
);
CREATE TABLE work (
person text not null,
job text not null
);
| person | job |
|--------|----------|
| tae | complain |
13 changes: 5 additions & 8 deletions out/coalesce.out
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
CREATE TABLE job (
name text not null,
billable real not null
);
CREATE TABLE work (
person text not null,
job text not null
);
| person | pay |
|--------|-----|
| mik | 2.0 |
| po | 0.5 |
| tay | 0.0 |
22 changes: 14 additions & 8 deletions out/cross_join.out
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
CREATE TABLE job (
name text not null,
billable real not null
);
CREATE TABLE work (
person text not null,
job text not null
);
| person | job | name | billable |
|--------|-----------|-----------|----------|
| mik | calibrate | calibrate | 1.5 |
| mik | calibrate | clean | 0.5 |
| mik | clean | calibrate | 1.5 |
| mik | clean | clean | 0.5 |
| mik | complain | calibrate | 1.5 |
| mik | complain | clean | 0.5 |
| po | clean | calibrate | 1.5 |
| po | clean | clean | 0.5 |
| po | complain | calibrate | 1.5 |
| po | complain | clean | 0.5 |
| tay | complain | calibrate | 1.5 |
| tay | complain | clean | 0.5 |
15 changes: 7 additions & 8 deletions out/delete_rows.out
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
CREATE TABLE job (
name text not null,
billable real not null
);
CREATE TABLE work (
person text not null,
job text not null
);
| person | job |
|--------|-----------|
| mik | calibrate |
| mik | clean |
| mik | complain |
| po | clean |
| po | complain |
Loading

0 comments on commit 1b6584f

Please sign in to comment.