SQL JOIN USING
A shorthand for ON — usable only when both tables happen to name their shared join column identically.
What & Why
USING (user_id) is a compact alternative to an equality ON clause when both inputs expose the same relationship column. growth.sessions and growth.events both contain user_id, so PostgreSQL can return one shared copy of that key.
See How It Works
BUSINESS QUESTION
Growth links sessions and events through their shared user_id column.
| id | user_id | started_at | ended_at | page_views | device |
|---|---|---|---|---|---|
| 5001 | 101 | 2024-01-16 14:20:00+00 | 2024-01-16 14:52:00+00 | 8 | desktop |
| 5002 | 102 | 2024-02-10 11:10:00+00 | 2024-02-10 11:18:00+00 | 3 | mobile |
| 5003 | 103 | 2024-03-13 08:10:00+00 | 2024-03-13 09:04:00+00 | 12 | desktop |
| 5004 | 104 | 2024-04-03 12:00:00+00 | NULL | 1 | tablet |
| 5005 | 105 | 2024-04-04 09:00:00+00 | 2024-04-04 09:21:00+00 | 7 | mobile |
| 5006 | 106 | 2024-04-05 10:15:00+00 | 2024-04-05 10:42:00+00 | 5 | tablet |
| 5007 | 107 | 2024-04-06 13:05:00+00 | 2024-04-06 13:38:00+00 | 10 | desktop |
| id | user_id | event_name | created_at | properties |
|---|---|---|---|---|
| 1001 | 101 | signup | 2024-01-15 09:12:00+00 | {"source":"organic"} |
| 1002 | 101 | activated | 2024-01-16 14:25:00+00 | {"step":"workspace"} |
| 1003 | 102 | signup | 2024-02-10 11:08:00+00 | {"source":"paid"} |
| 1004 | 103 | report_viewed | 2024-03-12 16:40:00+00 | {"report":"retention"} |
EXAMPLE QUERY
SELECT
user_id,
s.id AS session_id,
e.id AS event_id,
e.event_name
FROM growth.sessions s
JOIN growth.events e USING (user_id)
ORDER BY user_id, session_id, event_id;RESULT — exact output from the displayed Queryflo rows
| user_id | session_id | event_id | event_name |
|---|---|---|---|
| 101 | 5001 | 1001 | signup |
| 101 | 5001 | 1002 | activated |
| 102 | 5002 | 1003 | signup |
| 103 | 5003 | 1004 | report_viewed |
USING(user_id) produces the four real user-level session/event matches.
Now You Try
Practice this concept
Growth wants the first 100 session-event pairs joined through the same-named user_id column.
Available schema
growthPrefix tables with growth.table_name.
user_idsession_idevent_idevent_namegrowth.events| Column | Type |
|---|---|
| id | bigint |
| user_id | integer |
| event_name | text |
| created_at | timestamp with time zone |
| properties | jsonb |
| deprecated_metric | text |
growth.sessions| Column | Type |
|---|---|
| id | bigint |
| user_id | integer |
| started_at | timestamp with time zone |
| ended_at | timestamp with time zone |
| page_views | integer |
| device | text |
| internal_session_score | integer |
query.sql
Sign up free to try it on a real business scenario