Solve library SQL and Python tasks
Company: Meta
Role: Data Engineer
Category: Data Manipulation (SQL/Python)
Difficulty: medium
Interview Round: Technical Screen
You are given a library domain. Assume these tables:
- books(book_id, author_id, title)
- authors(author_id, name)
- copies(copy_id, book_id, condition) -- condition in {'good','fair','poor'}
- checkouts(checkout_id, copy_id, member_id, checkout_date, return_date, renew_count)
- members(member_id, name, referrer_member_id) -- referrer_member_id may be NULL
- reservations(reservation_id, member_id, book_id, reserve_date)
Write SQL for the following:
1) Return two metrics in one row:
(a) total_active_good = count of checkouts where return_date IS NULL and the associated copy's condition = 'good';
(b) pct_renew_gt_2 = among those active-good checkouts, the percentage whose renew_count > 2 (as a decimal rounded to 2 decimals). If the denominator is 0, return 0.00.
2) Among books that have more than 10 copies (counted from copies), compute for each book the maximum completed-checkout duration in days using return_date - checkout_date (ignore rows with return_date IS NULL). Return the top 3 books by this maximum duration, with columns (book_id, max_duration_days). Break ties by book_id ASC.
3) For each referred member m (members.referrer_member_id IS NOT NULL), compute the absolute difference between the number of reservations made by m and the number made by their referrer r. Return the row with the largest absolute difference, with columns (member_id, referrer_member_id, reservations_m, reservations_r, abs_diff). Break ties by member_id ASC.
Python tasks:
4) Given a list of tuples like [('category1',
4), ('category2',
6), ...], implement summarize(scores) that returns two integers: (total_sum, top3_max_sum) where total_sum is the sum of all scores; to compute top3_max_sum, first take the maximum score per category, then sum the top 3 category maxima (if fewer than 3 categories, sum what's available). Break ties by category name ASC when selecting top 3.
5) You receive a list of LogEntry objects where True means checkout and False means return:
class LogEntry:
def __init__(self, book_id: int, is_checkout: bool):
self.book_id = book_id
self.is_checkout = is_checkout
Implement is_valid_checkout_log(logs) -> bool that validates the sequence with these rules for each book_id:
(a) a return cannot occur before the first checkout;
(b) two consecutive checkouts without an intervening return are invalid;
(c) two consecutive returns are invalid. The check should run in O
(n) time and O
(n) space.
Overview: This question evaluates proficiency in advanced data manipulation and algorithmic reasoning across SQL and Python, covering aggregation, joins, filtering, windowing, date arithmetic, grouping, edge-case handling, and linear-time sequence validation for event logs.
Active good-condition checkouts and renewal rate
Using the library schema below, write a SQL query that returns a single row with two metrics:
1) total_active_good: the count of checkouts where return_date IS NULL and the associated copy's condition = 'good'.
2) pct_renew_gt_2: among those active-good checkouts, the percentage whose renew_count > 2, returned as a decimal rounded to 2 decimal places. If there are no active-good checkouts (denominator 0), return 0.00.
Return the result as one row with columns (total_active_good, pct_renew_gt_2).
Tables
books(book_id INT, author_id INT, title VARCHAR(100))
copies(copy_id INT, book_id INT, condition VARCHAR(10))
members(member_id INT, name VARCHAR(100), referrer_member_id INT)
checkouts(checkout_id INT, copy_id INT, member_id INT, checkout_date DATE, return_date DATE, renew_count INT)
reservations(reservation_id INT, member_id INT, book_id INT, reserve_date DATE)
Hints
- Filter first to active checkouts (return_date IS NULL) with copies in 'good' condition.
- Compute the percentage as SUM of a CASE expression divided by COUNT(*), and handle the zero-denominator case with a CASE expression.
Max completed checkout duration for high-copy-count books
Using the same library schema, write a SQL query that:
1) Considers only books that have more than 10 copies (based on the copies table).
2) For each such book, looks at completed checkouts only (rows in checkouts where return_date IS NOT NULL) and computes the maximum duration in days as (return_date - checkout_date).
3) Returns the top 3 books ordered by this maximum duration in descending order, breaking ties by book_id ascending.
Output columns should be (book_id, max_duration_days).
Tables
books(book_id INT, author_id INT, title VARCHAR(100))
copies(copy_id INT, book_id INT, condition VARCHAR(10))
members(member_id INT, name VARCHAR(100), referrer_member_id INT)
checkouts(checkout_id INT, copy_id INT, member_id INT, checkout_date DATE, return_date DATE, renew_count INT)
reservations(reservation_id INT, member_id INT, book_id INT, reserve_date DATE)
Hints
- First identify books with more than 10 copies using a subquery or CTE on the copies table.
- Join those books to checkouts and use MAX(return_date - checkout_date) grouped by book_id, then apply an ORDER BY with a LIMIT/FETCH to get the top 3.
Reservation difference between referred members and their referrers
Using the same library schema, write a SQL query that for each referred member m (rows in members where referrer_member_id IS NOT NULL) computes:
1) reservations_m: the number of reservations made by member m.
2) reservations_r: the number of reservations made by m's referrer r (members.member_id = m.referrer_member_id).
3) abs_diff: the absolute difference |reservations_m - reservations_r|.
Return only the single row with the largest abs_diff. If there is a tie on abs_diff, return the row with the smallest member_id among the tied members.
Output columns should be (member_id, referrer_member_id, reservations_m, reservations_r, abs_diff). Members with no reservations should be treated as having 0 reservations.
Tables
books(book_id INT, author_id INT, title VARCHAR(100))
copies(copy_id INT, book_id INT, condition VARCHAR(10))
members(member_id INT, name VARCHAR(100), referrer_member_id INT)
checkouts(checkout_id INT, copy_id INT, member_id INT, checkout_date DATE, return_date DATE, renew_count INT)
reservations(reservation_id INT, member_id INT, book_id INT, reserve_date DATE)
Hints
- First aggregate reservations per member, then join members to this aggregation twice: once for the referred member and once for the referrer.
- Use COALESCE for members with zero reservations and compute abs_diff with ABS, then order by abs_diff DESC and member_id ASC, limiting the result to one row.
Community answers
Answer by ginb
SELECT count() total_active_good ,coalesce( round( count(case when renew_count>2 then 1 else null end)1.0 / count(*) ,2) ,0) as pct_renew_gt_2FROM copies c join checkouts ch on c.copy_id=ch.copy_idwhere condition='good' and return_date is null
Answer by ginb
2
SELECT book_id,max(return_date-checkout_date) as max_duration_daysFROM checkouts ch join copies con c.copy_id=ch.copy_idgroup by 1having book_id in ( select book_id from copies group by 1 having count(*)>10)order by 2 desclimit 3