Learn SQL/Intermediate/Joins/SQL One-to-One Relationships

SQL One-to-One Relationships

Exactly one row on each side corresponds to exactly one row on the other — the least common of the three relationship patterns, but worth recognizing.

What & Why

A one-to-one relationship means each row in table A relates to at most one row in table B, and vice versa. This often shows up when a table is deliberately split in two — perhaps for security reasons, or to avoid a table with an unwieldy number of columns.

See How It Works

BUSINESS QUESTION

Growth reduces sessions to one latest-session row per user, then attaches that summary to each user once.

iduser_idstarted_atended_atpage_viewsdevice
50011012024-01-16 14:20:00+002024-01-16 14:52:00+008desktop
50021022024-02-10 11:10:00+002024-02-10 11:18:00+003mobile
50031032024-03-13 08:10:00+002024-03-13 09:04:00+0012desktop
50041042024-04-03 12:00:00+00NULL1tablet
50051052024-04-04 09:00:00+002024-04-04 09:21:00+007mobile
50061062024-04-05 10:15:00+002024-04-05 10:42:00+005tablet
50071072024-04-06 13:05:00+002024-04-06 13:38:00+0010desktop
idcreated_atcountrychannelplanactivated_atchurned_at
1012024-01-15 09:10:00+00USorganicpro2024-01-16 14:25:00+00NULL
1022024-02-10 11:05:00+00CApaidfreeNULL2024-03-20 10:00:00+00
1032024-03-12 16:35:00+00GBreferralpro2024-03-13 08:15:00+00NULL
1042024-04-01 13:20:00+00USorganicfree2024-04-03 12:00:00+00NULL
EXAMPLE QUERY
WITH latest_session AS (
  SELECT
    user_id,
    MAX(started_at) AS latest_session_at
  FROM growth.sessions
  GROUP BY user_id
)
SELECT
  u.id AS user_id,
  u.plan,
  s.latest_session_at
FROM growth.users u
LEFT JOIN latest_session s ON s.user_id = u.id
ORDER BY user_id;
RESULT — exact output from the displayed Queryflo rows
user_idplanlatest_session_at
101pro2024-01-16 14:20:00+00
102free2024-02-10 11:10:00+00
103pro2024-03-13 08:10:00+00
104free2024-04-03 12:00:00+00

The CTE reduces sessions to at most one row per displayed user.

Now You Try

Practice this concept

Growth wants the first 50 users with at most one latest-session summary row attached to each user.

Available schema
growth

Prefix tables with growth.table_name.

user_idplanlatest_session_at
growth.sessions
ColumnType
idbigint
user_idinteger
started_attimestamp with time zone
ended_attimestamp with time zone
page_viewsinteger
devicetext
internal_session_scoreinteger
growth.users
ColumnType
idinteger
created_attimestamp with time zone
countrytext
channeltext
plantext
activated_attimestamp with time zone
churned_attimestamp with time zone
legacy_user_codetext
query.sql
Intermediate business practice

Sign up free to try it on a real business scenario