Mutual Channel Connections

A medium SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
medium
Seniority
L4
Asked in
Google

Problem

Our chat platform stores one row per message, tagged with its sender and the channel it was posted to. Find the senders who have posted in both the '#engineering' and '#data-team' channels.

Two users. What channels do they share?

Tables

chat_msgs

Columns: msg_id INTEGER, channel TEXT, sender_id INTEGER, content TEXT, msg_type TEXT, sent_at TEXT, edited INTEGER, reply_to INTEGER

chat_msgs: 10 of 200 rows
msg_idchannelsender_idcontentmsg_typesent_ateditedreply_to
147#engineering197Anyone seeing increased latency?file2026-02-02 01:07:000NULL
194#incidents294PR #412 ready for reviewreaction2026-03-03 02:14:000NULL
241#random391Dashboard is downthread_reply2026-04-04 03:21:000NULL
288#deployments488Fixed the flaky testsystem2026-05-05 04:28:000NULL
335#data-team585Merged the migrationText2026-06-06 05:35:000NULL
382#general682NULLFILE2026-07-07 06:42:000NULL
429#engineering779LGTMtext2026-08-08 07:49:000NULL
476#incidents876👍file2026-09-09 08:56:0005
523#random973reaction2026-01-10 09:03:000NULL
570#deployments1070Can someone check the pipeline?thread_reply2026-02-11 10:10:000NULL

Expected output

First 5 of 8 rows
sender_id
585
1167
1749
2331
2913

Worked solution and explanation

What this problem is really asking

Strip the chat-app framing and this is a set intersection. You need the senders who show up in the #engineering set and in the #data-team set, computed as two independent membership checks joined by AND. The word that trips people is 'both': read it as a single channel IN ('#engineering', '#data-team') filter and you have quietly asked for everyone in either channel, a union. On this data that returns 25 senders instead of 8, because plenty of people post in one of the two rooms but never the other.


Build it in two halves

Step 1: Resolve each channel's senders separately

The senders who posted in #engineering are SELECT sender_id FROM chat_msgs WHERE channel = '#engineering', and the #data-team senders are the same query with the other literal. Each is its own set; keep them apart.

Step 2: Keep only the senders in both sets

Filter chat_msgs to rows whose sender_id sits in the first set AND in the second: sender_id IN (...) AND sender_id IN (...). The AND is the intersection. Swap it for OR, or fold the two literals into one IN list, and the meaning flips to 'either channel' and the count jumps to 25.

Step 3: Collapse repeat posters to one row

Each qualifying sender has several messages in each channel, so the raw filter returns one row per message: four rows per person here. Wrap the projection in SELECT DISTINCT sender_id so the output is the set of people, not their message volume.


The solution

Two membership subqueries, intersected with AND
SELECT DISTINCT sender_id
FROM chat_msgs
WHERE sender_id IN (SELECT sender_id FROM chat_msgs WHERE channel = '#engineering')
  AND sender_id IN (SELECT sender_id FROM chat_msgs WHERE channel = '#data-team')

Common follow-up questions