Skip to content

Commit 6464b45

Browse files
authored
Merge pull request #7 from fhdsl/fall-2025
week 1 ready
2 parents e96b0bb + 55838d5 commit 6464b45

8 files changed

Lines changed: 4204 additions & 67 deletions

File tree

img/Intro_to_Databases.png

1.04 MB
Loading

img/omop0.png

93.3 KB
Loading

img/omop1.png

-82.6 KB
Loading
1.04 MB
Loading

slides/lesson1_slides.html

Lines changed: 3788 additions & 0 deletions
Large diffs are not rendered by default.

slides/lesson1_slides.qmd

Lines changed: 357 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
---
2+
title: "W1: Database Concepts, DESCRIBE, SELECT, WHERE"
3+
format:
4+
revealjs:
5+
smaller: true
6+
scrollable: true
7+
echo: true
8+
embed-resources: true
9+
output-location: fragment
10+
---
11+
12+
## Welcome!
13+
14+
![](images/Intro_to_Databases.png){width="400"}
15+
16+
Please [sign-up for an account at Posit Cloud](https://login.posit.cloud/register "https://login.posit.cloud/register") and accept our classroom invitation here: <https://posit.cloud/spaces/689711/join?access_code=8kse5IYlL4kHIqZvKaQ6mXp8IMibFayMa10I8Izn>
17+
18+
## Introductions
19+
20+
- Who am I?
21+
22+
. . .
23+
24+
- What is [DaSL](https://hutchdatascience.org/) / [OCDO](https://ocdo.fredhutch.org/) ?
25+
26+
. . .
27+
28+
- Who are you?
29+
30+
- Name, pronouns, group you work in
31+
32+
- What you want to get out of the class
33+
34+
- What has brought you joy lately?
35+
36+
. . .
37+
38+
- Our wonderful TAs!
39+
40+
## Goals of the course
41+
42+
. . .
43+
44+
-
45+
46+
. . .
47+
48+
-
49+
50+
## Content of the course
51+
52+
1. Database Concepts, `DESCRIBE`, `SELECT`, `WHERE`
53+
54+
2. `JOIN`ing tables
55+
56+
3. \[No class week\]
57+
58+
4. Calculating new fields, `GROUP BY`, `CASE WHEN`, `HAVING`
59+
60+
5. Subqueries, Views, **Pizza**
61+
62+
## Culture of the course
63+
64+
. . .
65+
66+
- Challenge: We are learning a new language, but you already have a full-time job.
67+
68+
. . .
69+
70+
- *Teach not for mastery, but teach for empowerment to learn effectively.*
71+
72+
. . .
73+
74+
- *Teach at learner's pace.*
75+
76+
## Culture of the course
77+
78+
- Challenge: We sometimes struggle with our data science problems in isolation, unaware that other folks are working on similar things.
79+
80+
. . .
81+
82+
- *We learn and work better with our peers.*
83+
84+
. . .
85+
86+
- *We encourage discussion and questions, as others often have similar questions also.*
87+
88+
## Format of the course
89+
90+
. . .
91+
92+
- Hybrid, and recordings will be available.
93+
94+
. . .
95+
96+
- 1 hour exercises after each session are encouraged for practice.
97+
98+
. . .
99+
100+
- Office hours 11:30-Noon before class.
101+
102+
## Badge of completion
103+
104+
![](images/Intro_to_Databases.png){width="400"}
105+
106+
We offer a [badge of completion](https://www.credly.com/org/fred-hutch/badge/intro-to-sql) when you finish the course!
107+
108+
What it is:
109+
110+
- A display of what you accomplished in the course, shareable in your professional networks such as LinkedIn, similar to online education services such as Coursera.
111+
112+
What it isn't:
113+
114+
- Accreditation through an university or degree-granting program.
115+
116+
. . .
117+
118+
Requirements:
119+
120+
- Complete badge-required sections of the exercises for 3 out of 4 assignments.
121+
122+
## Databases...
123+
124+
- What are some Databases you are interested in?
125+
126+
. . .
127+
128+
- Why do we need a Database Management System (DBMS) to manage it? (What could go wrong in managing a spreadsheet?)
129+
130+
. . .
131+
132+
Benefits of a DBMS:
133+
134+
- **Data Integrity:** What are the rules within the database? If it is a medical database, does a patient always have a visit site? How do we deal with missing data? Are duplicated entries allowed?
135+
136+
. . .
137+
138+
- **Implementation:** How do you find a particular record? What if we now want to create a new application that uses the same database? What if that application is running on a different machine?
139+
140+
. . .
141+
142+
- **Durability:** What if the machine crashes while our program is updating a record? What if we want to replicate the database on multiple machines?
143+
144+
## Database Management System (DBMS) consists of
145+
146+
- **A user interface** - how users interact with the database. In this class, our main way of interacting with databases is SQL (Structured Query Language).
147+
148+
- **An execution engine** - a software system that queries the data in storage. These can live on our machine, on a server within our network, or a server on the cloud.
149+
150+
- **Data Storage** - the physical location where the data is stored.
151+
152+
## DBMS examples
153+
154+
| | This class | Example Hutch on-site database system | Example Hutch cloud database system |
155+
|-----------------|-----------------|---------------------|-------------------|
156+
| **User Interface** | SQL | SQL | SQL |
157+
| **Execution Engine** | DuckDB | SQL Server | Databrick/Snowflake |
158+
| **Data Storage** | File on our machine | FH Shared Storage | Amazon S3 Bucket |
159+
160+
## Our underlying data model
161+
162+
Relational Database: Data is organized into multiple tables. Tables are connected via columns that share the same elements across tables.
163+
164+
. . .
165+
166+
Person table
167+
168+
| person_id | year_of_birth | gender_source_value |
169+
|-----------|---------------|---------------------|
170+
| 001 | 1/1/1999 | F |
171+
| 002 | 12/31/1999 | F |
172+
| 003 | 6/1/2000 | M |
173+
174+
. . .
175+
176+
Procedure Occurrence table
177+
178+
| procedure_occurrence_id | person_id | procedure_datetime |
179+
|-------------------------|-----------|--------------------|
180+
| 101 | 001 | 4/1/2010 |
181+
| 102 | 003 | 6/1/2022 |
182+
| 103 | 004 | 5/1/2001 |
183+
184+
. . .
185+
186+
**Entity Relationship Diagram**
187+
188+
![](../img/omop0.png){width="550"}
189+
190+
## Let's get started: connecting to the database
191+
192+
```{r, warning=FALSE}
193+
library(DBI)
194+
195+
con <- DBI::dbConnect(duckdb::duckdb(), "../data/GiBleed_5.3_1.1.duckdb")
196+
```
197+
198+
## What are the available tables?
199+
200+
```{sql connection="con"}
201+
SHOW TABLES
202+
```
203+
204+
## Describing a table
205+
206+
```{sql connection="con"}
207+
DESCRIBE person
208+
```
209+
210+
## Data Types
211+
212+
If you look at the `column_type` for one of the `DESCRIBE` statements above, you'll notice there are different data types:
213+
214+
- `INTEGER`
215+
- `TIMESTAMP`
216+
- `DATE`
217+
- `VARCHAR`
218+
219+
You can see all of the [datatypes that are available in DuckDB here](https://duckdb.org/docs/sql/data_types/overview.html).
220+
221+
## `SELECT` and `FROM`
222+
223+
`SELECT` is a clause that lets you pick out columns of interest. If you want all columns, use `*`.
224+
225+
`FROM` is a clause that lets you decide which table to work with.
226+
227+
. . .
228+
229+
```{sql connection="con"}
230+
SELECT *
231+
FROM person
232+
LIMIT 10;
233+
```
234+
235+
. . .
236+
237+
`LIMIT n` let's you look at the first n entries.
238+
239+
We put multiple SQL **clauses** together to form a **query**.
240+
241+
. . .
242+
243+
Try it out yourself on `procedure_occurrence` table. Why is there a `person_id` column in this table as well?
244+
245+
## `SELECT` for specific columns
246+
247+
Instead of `*` for all columns, we can specify the columns of interest:
248+
249+
```{sql connection="con"}
250+
SELECT person_id, birth_datetime, gender_concept_id
251+
FROM person
252+
LIMIT 10;
253+
```
254+
255+
. . .
256+
257+
Try add `race_concept_id` and `year_of_birth` to your `SELECT` query.
258+
259+
## `WHERE` - filtering our table
260+
261+
Adding `WHERE` to our SQL statement lets us add filtering to our query:
262+
263+
```{sql}
264+
#| connection: "con"
265+
SELECT person_id, gender_source_value, race_source_value, year_of_birth
266+
FROM person
267+
WHERE year_of_birth < 2000
268+
```
269+
270+
. . .
271+
272+
You don't need to include the columns you're filtering via `WHERE` in the `SELECT` part of the statement:
273+
274+
```{sql}
275+
#| connection: "con"
276+
SELECT person_id, gender_source_value, race_source_value
277+
FROM person
278+
WHERE year_of_birth < 2000
279+
```
280+
281+
## Single quotes and `WHERE`
282+
283+
Single quotes ('M') refer to values, and double quotes refer to columns ("person_id").
284+
285+
This will trip you up several times if you're not used to it.
286+
287+
```{sql}
288+
#| connection: "con"
289+
SELECT person_id, gender_source_value
290+
FROM person
291+
WHERE gender_source_value = 'M'
292+
LIMIT 10;
293+
```
294+
295+
## `COUNT` - how many entries?
296+
297+
Sometimes you want to know the *size* of your result, not necessarily return the entire set of results. That is what `COUNT` is for.
298+
299+
```{sql}
300+
#| connection: "con"
301+
SELECT COUNT(*)
302+
FROM procedure_occurrence;
303+
```
304+
305+
. . .
306+
307+
Similarly, when we want to count the number of `person_id`s returned, we can use `COUNT(person_id)`:
308+
309+
```{sql}
310+
#| connection: "con"
311+
SELECT COUNT(procedure_concept_id)
312+
FROM procedure_occurrence;
313+
```
314+
315+
## `COUNT DISTINCT` for unique entries
316+
317+
When you have repeated values, `COUNT(DISTINCT )` can help you find the number of unique values in a column:
318+
319+
```{sql}
320+
#| connection: "con"
321+
SELECT COUNT(DISTINCT procedure_concept_id)
322+
FROM procedure_occurrence
323+
```
324+
325+
. . .
326+
327+
We can also return the actual `DISTINCT` values by removing `COUNT`:
328+
329+
```{sql}
330+
#| connection: "con"
331+
SELECT DISTINCT procedure_concept_id
332+
FROM procedure_occurrence;
333+
```
334+
335+
. . .
336+
337+
Your turn: Count the distinct values of `gender_source_value` in `person.`
338+
339+
## Revisiting `DESCRIBE`
340+
341+
One of the important properties of data in a relational database is that there are no *repeat rows* in the database. Each table that meets this restriction has what is called a *primary key*.
342+
343+
```{sql connection="con"}
344+
DESCRIBE person
345+
```
346+
347+
. . .
348+
349+
We\'ll see that primary keys need to be unique (so they can map to each row).
350+
351+
## Always close the connection
352+
353+
When we're done, it's best to close the connection with `dbDisconnect()`.
354+
355+
```{r}
356+
dbDisconnect(con)
357+
```

0 commit comments

Comments
 (0)