Watch the video solution for Find Longest Calls, a medium level problem involving Database. This walkthrough by Everyday Data Science has 529 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Table: Contacts
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| first_name | varchar |
| last_name | varchar |
+-------------+---------+
id is the primary key (column with unique values) of this table.
id is a foreign key (reference column) to Calls table.
Each row of this table contains id, first_name, and last_name.
Table: Calls
+-------------+------+
| Column Name | Type |
+-------------+------+
| contact_id | int |
| type | enum |
| duration | int |
+-------------+------+
(contact_id, type, duration) is the primary key (column with unique values) of this table.
type is an ENUM (category) type of ('incoming', 'outgoing').
Each row of this table contains information about calls, comprising of contact_id, type, and duration in seconds.
Write a solution to find the three longest incoming and outgoing calls.
Return the result table ordered by type, duration, and first_name in descending order and duration must be formatted as HH:MM:SS.
The result format is in the following example.
Example 1:
Input:
Contacts table:
+----+------------+-----------+ | id | first_name | last_name | +----+------------+-----------+ | 1 | John | Doe | | 2 | Jane | Smith | | 3 | Alice | Johnson | | 4 | Michael | Brown | | 5 | Emily | Davis | +----+------------+-----------+
Calls table:
+------------+----------+----------+
| contact_id | type | duration |
+------------+----------+----------+
| 1 | incoming | 120 |
| 1 | outgoing | 180 |
| 2 | incoming | 300 |
| 2 | outgoing | 240 |
| 3 | incoming | 150 |
| 3 | outgoing | 360 |
| 4 | incoming | 420 |
| 4 | outgoing | 200 |
| 5 | incoming | 180 |
| 5 | outgoing | 280 |
+------------+----------+----------+
Output:
+-----------+----------+-------------------+
| first_name| type | duration_formatted|
+-----------+----------+-------------------+
| Alice | outgoing | 00:06:00 |
| Emily | outgoing | 00:04:40 |
| Jane | outgoing | 00:04:00 |
| Michael | incoming | 00:07:00 |
| Jane | incoming | 00:05:00 |
| Emily | incoming | 00:03:00 |
+-----------+----------+-------------------+
Explanation:
Note: Output table is sorted by type, duration, and first_name in descending order.
Problem Overview: The task asks you to identify the longest phone calls recorded in a call log table. Each record represents a call between two users with a duration. The goal is to determine which calls have the maximum duration under the required grouping conditions (such as per caller or user pair) and return the relevant rows.
Approach 1: Aggregation + Join (O(n log n) time, O(n) space)
A common starting point is to compute the maximum call duration using GROUP BY. For example, group rows by the entity you care about (such as caller_id or a caller–receiver pair) and compute MAX(duration). That subquery gives the longest duration per group. Then perform an equi-join between the original Calls table and the aggregated result to retrieve the full rows that match the maximum duration. This approach works well when the grouping logic is simple and you only need rows matching the computed maximum.
Approach 2: Equi-Join + Window Function (O(n log n) time, O(n) space)
The cleaner and usually preferred solution uses a window function such as ROW_NUMBER() or RANK(). First join any required tables using an equi-join (for example, joining call records with user metadata if needed). Then apply a window function with PARTITION BY to define the group (such as per caller or per call pair) and ORDER BY duration DESC so the longest call appears first in each partition. Assign row numbers and filter for row_number = 1. This directly returns the longest call in each group without needing a separate aggregation join.
Window functions are powerful because they operate on ordered partitions of data. Instead of collapsing rows like GROUP BY, they keep all rows visible while still computing rankings or aggregates. That makes them ideal for "top‑N per group" problems commonly seen in SQL interview questions and database analytics.
These techniques appear frequently in database interview problems involving SQL, especially when identifying maximum values within groups or ranking records. Understanding how ROW_NUMBER, RANK, and DENSE_RANK behave within partitions is key for problems involving window functions and relational joins like database equi-joins.
Recommended for interviews: The window function approach with ROW_NUMBER() is what most interviewers expect. It is concise, expressive, and scales well for "top record per group" queries. Showing the aggregation + join method first demonstrates understanding of relational operations, but the window function solution signals stronger SQL fluency.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Aggregation + Join | O(n log n) | O(n) | Useful when computing MAX/MIN per group and then retrieving matching rows |
| Equi-Join + Window Function (ROW_NUMBER) | O(n log n) | O(n) | Best for top‑N per group queries and modern SQL interview problems |