Coding questions · Intuit
Longest Meeting-Free Business-Hours Block per Employee and Day
Find each employee’s longest meeting-free business-hours interval using clipped attendance, merged overlaps, complete day coverage, and SQL window logic.
A company wants to measure uninterrupted time available for project work. Given meeting attendance intervals, return the longest meeting-free block within business hours for every employee on every supplied business day.
Write one read-only PostgreSQL query over these tables:
employees(employee_id BIGINT PRIMARY KEY)
business_days(work_date DATE PRIMARY KEY,
start_at TIMESTAMPTZ NOT NULL,
end_at TIMESTAMPTZ NOT NULL)
meeting_attendance(employee_id BIGINT NOT NULL,
meeting_id TEXT NOT NULL,
join_time TIMESTAMPTZ NOT NULL,
leave_time TIMESTAMPTZ NOT NULL)
Return employee_id, work_date, and longest_free_seconds as a nonnegative integer, ordered by employee_id, then work_date.
Constraints & Assumptions
- The report supplies attendance columns but leaves the roster and business-hours calendar unspecified. The two supplementary fixture tables explicitly define those missing inputs for this SQL practice version.
- Every listed employee is in scope for every supplied business day. Include employees/days with no meetings.
- Each business interval satisfies
start_at < end_at, has whole-second timestamps, and belongs to the statedwork_datein the company's chosen calendar. Use those absolute boundaries directly rather than guessing a timezone from the date. - Attendance rows have
join_time < leave_time, whole-second timestamps, and valid employee IDs. Duplicate or overlapping rows may exist, including multiple joins to one meeting. - Intervals are half-open. Clip each attendance interval to the business interval; ignore it if the clipped intersection is empty.
- Merge overlapping or touching occupied intervals before measuring free gaps. Count gaps before the first meeting and after the last meeting as well as gaps between meetings.
- Attendance may span multiple business days. Compute its intersection with each supplied day independently.
- An employee with no occupied time on a day has the full business interval free; an employee occupied for the entire interval has zero free seconds.
Examples
If business hours are 09:00–17:00 and an employee attends 09:30–10:30 and 10:00–11:00, the merged occupied interval is 09:30–11:00. The longest free block is 11:00–17:00, or 21,600 seconds.
If another employee has no meetings that day, return 28,800 seconds for that employee/day. Do not omit the row because attendance is absent.
Hint: Compare with the furthest prior end
A meeting can be contained inside an earlier longer meeting. When assigning occupied-interval groups, compare its start with the running maximum prior end rather than only the immediately preceding row's end.
Longest Meeting-Free Business-Hours Block per Employee and Day
Table employees
| column | type | constraints |
|---|---|---|
| employee_id | BIGINT | PRIMARY KEY |
Sample data:
| employee_id |
|---|
| 3000000001 |
| 42 |
| 7 |
| 23 |
Table business_days
| column | type | constraints |
|---|---|---|
| work_date | DATE | PRIMARY KEY |
| start_at | TIMESTAMP WITH TIME ZONE | NOT NULL |
| end_at | TIMESTAMP WITH TIME ZONE | NOT NULL |
Sample data:
| end_at | start_at | work_date |
|---|---|---|
| 2026-09-15T17:00:00+00:00 | 2026-09-15T09:00:00+00:00 | 2026-09-15 |
| 2026-09-14T17:00:00+00:00 | 2026-09-14T09:00:00+00:00 | 2026-09-14 |
Table meeting_attendance
| column | type | constraints |
|---|---|---|
| employee_id | BIGINT | NOT NULL |
| meeting_id | TEXT | NOT NULL |
| join_time | TIMESTAMP WITH TIME ZONE | NOT NULL |
| leave_time | TIMESTAMP WITH TIME ZONE | NOT NULL |
Sample data:
| employee_id | join_time | leave_time | meeting_id |
|---|---|---|---|
| 23 | 2026-09-14T15:00:00+00:00 | 2026-09-14T16:00:00+00:00 | afternoon |
| 7 | 2026-09-14T15:00:00+00:00 | 2026-09-14T16:00:00+00:00 | inside-late |
| 42 | 2026-09-14T13:30:00+00:00 | 2026-09-14T17:00:00+00:00 | late-block |
| 7 | 2026-09-14T09:00:00+00:00 | 2026-09-14T16:30:00+00:00 | enclosing |
| 7 | 2026-09-14T09:30:00+00:00 | 2026-09-14T10:00:00+00:00 | inside-short |
| 7 | 2026-09-14T09:30:00+00:00 | 2026-09-14T10:00:00+00:00 | inside-short |
| 7 | 2026-09-15T10:00:00+00:00 | 2026-09-15T11:00:00+00:00 | overlap-b |
| 23 | 2026-09-14T10:00:00+00:00 | 2026-09-14T11:00:00+00:00 | morning |
| 23 | 2026-09-14T17:00:00+00:00 | 2026-09-15T18:00:00+00:00 | overnight |
| 7 | 2026-09-15T09:30:00+00:00 | 2026-09-15T10:30:00+00:00 | overlap-a |
| 42 | 2026-09-15T09:00:00+00:00 | 2026-09-15T10:00:00+00:00 | early-block |
| 7 | 2026-09-15T14:00:00+00:00 | 2026-09-15T15:00:00+00:00 | later-block |
Expected output
| employee_id | work_date | longest_free_seconds |
|---|---|---|
| 7 | 2026-09-14 | 1800 |
| 7 | 2026-09-15 | 10800 |
| 23 | 2026-09-14 | 14400 |
| 23 | 2026-09-15 | 0 |
| 42 | 2026-09-14 | 16200 |
| 42 | 2026-09-15 | 25200 |
| 3000000001 | 2026-09-14 | 28800 |
| 3000000001 | 2026-09-15 | 28800 |