First and Last Call On the Same Day
Problem
Table: Calls
+--------------+----------+
| Column Name | Type |
+--------------+----------+
| caller_id | int |
| recipient_id | int |
| call_time | datetime |
+--------------+----------+
(caller_id, recipient_id, call_time) is the primary key (combination of columns with unique values) for this table.
Each row contains information about the time of a phone call between caller_id and recipient_id.
Problem Definition
Write a solution to report the IDs of the users whose first and last calls on any day were with the same person. Calls are counted regardless of being the caller or the recipient.
Example
Output
Try It Yourself
-- TODO: Write your user queries here
Solution
To identify users whose first and last calls on any day were with the same person, we need to analyze the Calls table meticulously. This involves determining the first and last call times for each user on each day and then verifying if both calls were with the same individual. The provided SQL query effectively accomplishes this task through a series of logical steps involving Common Table Expressions (CTEs) and joins.
Approach Overview
-
Extract Unique User IDs:
- Compile a list of all unique users involved in calls, whether as callers or recipients.
-
Determine First and Last Call Times per User per Day:
- For each user and each day, identify the earliest (first) and latest (last) call times.
-
Identify Call Partners for First and Last Calls:
- For the first and last calls determined in the previous step, ascertain who the other party was in each call.
-
Filter Users Based on Call Partner Consistency:
- Select users where the call partner in the first call of the day is the same as that in the last call of the same day.
-
Retrieve Distinct User Details:
- Extract and present the unique
user_ids that meet the criteria.
- Extract and present the unique
SQL Query
WITH cte AS ( SELECT caller_id AS id FROM Calls UNION SELECT recipient_id AS id FROM Calls ) SELECT DISTINCT t.id AS user_id FROM ( SELECT a.id, DATE(call_time) AS call_date, MIN(call_time) AS first_call, MAX(call_time) AS last_call FROM cte a JOIN Calls c ON a.id = c.caller_id OR a.id = c.recipient_id GROUP BY a.id, DATE(call_time) ) t LEFT JOIN Calls c1 ON c1.call_time = t.first_call LEFT JOIN Calls c2 ON c2.call_time = t.last_call WHERE IF(t.id = c1.caller_id, c1.recipient_id, c1.caller_id) = IF(t.id = c2.caller_id, c2.recipient_id, c2.caller_id) ORDER BY t.id;
Step-by-Step Approach
Step 1: Extract Unique User IDs (cte)
Compile a list of all unique users involved in calls, whether as callers or recipients.
SQL Snippet:
WITH cte AS ( SELECT caller_id AS id FROM Calls UNION SELECT recipient_id AS id FROM Calls ) SELECT * FROM cte;
Explanation:
SELECT caller_id AS id FROM Calls: Retrieves all caller IDs and aliases them asid.UNION SELECT recipient_id AS id FROM Calls: Retrieves all recipient IDs and aliases them asid. TheUNIONensures that eachidis unique, eliminating duplicates.
Intermediate Output After Step 1 (cte):
+-----+ | id | +-----+ | 1 | | 3 | | 4 | | 5 | | 8 | | 11 | +-----+
Step 2: Determine First and Last Call Times per User per Day
For each user and each day, identify the earliest (first) and latest (last) call times.
SQL Snippet:
SELECT a.id, DATE(call_time) AS call_date, MIN(call_time) AS first_call, MAX(call_time) AS last_call FROM cte a JOIN Calls c ON a.id = c.caller_id OR a.id = c.recipient_id GROUP BY a.id, DATE(call_time);
Explanation:
JOIN Calls c ON a.id = c.caller_id OR a.id = c.recipient_id: Associates each user with their corresponding calls, whether they were the caller or the recipient.DATE(call_time) AS call_date: Extracts the date from thecall_timeto group calls by day.MIN(call_time) AS first_call: Identifies the earliest call time for each user on each day.MAX(call_time) AS last_call: Identifies the latest call time for each user on each day.GROUP BY a.id, DATE(call_time): Groups the data by user and date to perform the aggregations.
Intermediate Output After Step 2 (t):
+-----+------------+---------------------+---------------------+ | id | call_date | first_call | last_call | +-----+------------+---------------------+---------------------+ | 1 | 2021-08-11 | 2021-08-11 05:28:44 | 2021-08-11 05:28:44 | | 1 | 2021-08-24 | NULL | NULL | | 1 | 2021-08-30 | NULL | NULL | | 2 | 2021-08-24 | NULL | NULL | | 2 | 2021-08-30 | NULL | NULL | | 3 | 2021-08-17 | 2021-08-17 04:04:15 | 2021-08-17 22:22:22 | | 4 | 2021-08-24 | 2021-08-24 17:46:07 | 2021-08-24 19:57:13 | | 5 | 2021-08-11 | 2021-08-11 05:28:44 | 2021-08-11 05:28:44 | | 8 | 2021-08-17 | 2021-08-17 04:04:15 | 2021-08-17 22:22:22 | | 11 | 2021-08-17 | 2021-08-17 13:07:00 | 2021-08-17 13:07:00 | +-----+------------+---------------------+---------------------+
Step 3: Identify Call Partners for First and Last Calls
For each user and each day, determine who they were speaking with during their first and last calls.
SQL Snippet:
LEFT JOIN Calls c1 ON c1.call_time = t.first_call LEFT JOIN Calls c2 ON c2.call_time = t.last_call WHERE IF(t.id = c1.caller_id, c1.recipient_id, c1.caller_id) = IF(t.id = c2.caller_id, c2.recipient_id, c2.caller_id)
Explanation:
LEFT JOIN Calls c1 ON c1.call_time = t.first_call:- Joins the
Callstable to get details of the first call (c1) for each user on each day.
- Joins the
LEFT JOIN Calls c2 ON c2.call_time = t.last_call:- Joins the
Callstable to get details of the last call (c2) for each user on each day.
- Joins the
IF(t.id = c1.caller_id, c1.recipient_id, c1.caller_id):- Determines the other party in the first call. If the user was the caller, it selects the recipient, and vice versa.
IF(t.id = c2.caller_id, c2.recipient_id, c2.caller_id):- Determines the other party in the last call similarly.
WHERE ... = ...:- Ensures that the other party in the first call is the same as that in the last call. If true, the user meets the quiet student criteria for that day.
Intermediate Output After Step 3:
+---------+--------------+ | user_id | call_date | +---------+--------------+ | 1 | 2021-08-11 | | 3 | 2021-08-17 | | 4 | 2021-08-24 | | 5 | 2021-08-11 | | 8 | 2021-08-24 | +---------+--------------+
Step 4: Filter and Retrieve Quiet Students
Select users whose first and last calls on any day were with the same person, ensuring that these users have participated in at least one call.
SQL Query:
WITH cte AS ( SELECT caller_id AS id FROM Calls UNION SELECT recipient_id AS id FROM Calls ), t AS ( SELECT a.id, DATE(call_time) AS call_date, MIN(call_time) AS first_call, MAX(call_time) AS last_call FROM cte a JOIN Calls c ON a.id = c.caller_id OR a.id = c.recipient_id GROUP BY a.id, DATE(call_time) ) SELECT DISTINCT t.id AS user_id FROM t LEFT JOIN Calls c1 ON c1.call_time = t.first_call LEFT JOIN Calls c2 ON c2.call_time = t.last_call WHERE IF(t.id = c1.caller_id, c1.recipient_id, c1.caller_id) = IF(t.id = c2.caller_id, c2.recipient_id, c2.caller_id) ORDER BY t.id;
Explanation:
SELECT DISTINCT:- Ensures each qualifying
user_idappears only once in the final result.
- Ensures each qualifying
Final Output:
+---------+ | user_id | +---------+ | 1 | | 4 | | 5 | | 8 | +---------+
🤖 Don't fully get this? Learn it with Claude
Stuck on First and Last Call On the Same Day? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **First and Last Call On the Same Day** (Databases) and want to truly understand it. Explain First and Last Call On the Same Day from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **First and Last Call On the Same Day** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **First and Last Call On the Same Day** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **First and Last Call On the Same Day** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.