cswork / libraryOpen practice workspace

Coding questions · Meta

Solve library SQL and Python tasks

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.

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.

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).

Table books

columntypeconstraints
book_idINTPRIMARY KEY
author_idINTNOT NULL
titleVARCHAR(100)NOT NULL

Sample data:

author_idbook_idtitle
11Data Structures
22Databases 101
13Python Basics
34Algorithms Advanced

Table copies

columntypeconstraints
copy_idINTPRIMARY KEY
book_idINTNOT NULL
conditionVARCHAR(10)NOT NULL

Sample data:

book_idconditioncopy_id
1good1
1good2
1fair3
1good4
1poor5
1good6
1good7
1good8
1good9
1good10
1good11
1good12
2good13
2fair14
2good15
2good16
2good17
2poor18
2good19
2good20
2good21
2good22
2good23
3good24
3good25
3fair26
3good27
3poor28
4good29
4good30
4fair31

Table members

columntypeconstraints
member_idINTPRIMARY KEY
nameVARCHAR(100)NOT NULL
referrer_member_idINT

Sample data:

member_idnamereferrer_member_id
1MikeNULL
2Nina1
3Oliver1
4Priya2
5QuinnNULL

Table checkouts

columntypeconstraints
checkout_idINTPRIMARY KEY
copy_idINTNOT NULL
member_idINTNOT NULL
checkout_dateDATENOT NULL
return_dateDATE
renew_countINTNOT NULL

Sample data:

checkout_datecheckout_idcopy_idmember_idrenew_countreturn_date
2025-05-011113NULL
2025-05-1022212025-05-20
2025-05-153311NULL
2025-05-054432NULL
2025-04-0155242025-04-10
2025-03-016615NULL
2025-01-01713102025-01-20
2025-02-10814212025-02-12
2025-03-0591531NULL
2025-01-01107222025-02-15

Table reservations

columntypeconstraints
reservation_idINTPRIMARY KEY
member_idINTNOT NULL
book_idINTNOT NULL
reserve_dateDATENOT NULL

Sample data:

book_idmember_idreservation_idreserve_date
1112025-05-01
1222025-05-02
2232025-05-03
2342025-05-04
3352025-05-05
4362025-05-06
1472025-05-07
2482025-05-08
3492025-05-09
21102025-05-10
32112025-05-11

Expected output

A single row summarizing the number of active checkouts for copies in 'good' condition and the percentage of those active-good checkouts with renew_count > 2, rounded to 2 decimal places.

pct_renew_gt_2total_active_good
0.54

Hints

  1. Filter first to active checkouts (return_date IS NULL) with copies in 'good' condition.
  2. 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).

Table books

columntypeconstraints
book_idINTPRIMARY KEY
author_idINTNOT NULL
titleVARCHAR(100)NOT NULL

Sample data:

author_idbook_idtitle
11Data Structures
22Databases 101
13Python Basics
34Algorithms Advanced

Table copies

columntypeconstraints
copy_idINTPRIMARY KEY
book_idINTNOT NULL
conditionVARCHAR(10)NOT NULL

Sample data:

book_idconditioncopy_id
1good1
1good2
1fair3
1good4
1poor5
1good6
1good7
1good8
1good9
1good10
1good11
1good12
2good13
2fair14
2good15
2good16
2good17
2poor18
2good19
2good20
2good21
2good22
2good23
3good24
3good25
3fair26
3good27
3poor28
4good29
4good30
4fair31

Table members

columntypeconstraints
member_idINTPRIMARY KEY
nameVARCHAR(100)NOT NULL
referrer_member_idINT

Sample data:

member_idnamereferrer_member_id
1MikeNULL
2Nina1
3Oliver1
4Priya2
5QuinnNULL

Table checkouts

columntypeconstraints
checkout_idINTPRIMARY KEY
copy_idINTNOT NULL
member_idINTNOT NULL
checkout_dateDATENOT NULL
return_dateDATE
renew_countINTNOT NULL

Sample data:

checkout_datecheckout_idcopy_idmember_idrenew_countreturn_date
2025-05-011113NULL
2025-05-1022212025-05-20
2025-05-153311NULL
2025-05-054432NULL
2025-04-0155242025-04-10
2025-03-016615NULL
2025-01-01713102025-01-20
2025-02-10814212025-02-12
2025-03-0591531NULL
2025-01-01107222025-02-15

Table reservations

columntypeconstraints
reservation_idINTPRIMARY KEY
member_idINTNOT NULL
book_idINTNOT NULL
reserve_dateDATENOT NULL

Sample data:

book_idmember_idreservation_idreserve_date
1112025-05-01
1222025-05-02
2232025-05-03
2342025-05-04
3352025-05-05
4362025-05-06
1472025-05-07
2482025-05-08
3492025-05-09
21102025-05-10
32112025-05-11

Expected output

For books that have more than 10 copies, returns up to 3 rows with each book's maximum completed-checkout duration (in days), ordered by this duration descending and then book_id ascending. Based on the sample data, only books 1 and 2 qualify.

book_idmax_duration_days
145
219

Hints

  1. First identify books with more than 10 copies using a subquery or CTE on the copies table.
  2. 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.

Table books

columntypeconstraints
book_idINTPRIMARY KEY
author_idINTNOT NULL
titleVARCHAR(100)NOT NULL

Sample data:

author_idbook_idtitle
11Data Structures
22Databases 101
13Python Basics
34Algorithms Advanced

Table copies

columntypeconstraints
copy_idINTPRIMARY KEY
book_idINTNOT NULL
conditionVARCHAR(10)NOT NULL

Sample data:

book_idconditioncopy_id
1good1
1good2
1fair3
1good4
1poor5
1good6
1good7
1good8
1good9
1good10
1good11
1good12
2good13
2fair14
2good15
2good16
2good17
2poor18
2good19
2good20
2good21
2good22
2good23
3good24
3good25
3fair26
3good27
3poor28
4good29
4good30
4fair31

Table members

columntypeconstraints
member_idINTPRIMARY KEY
nameVARCHAR(100)NOT NULL
referrer_member_idINT

Sample data:

member_idnamereferrer_member_id
1MikeNULL
2Nina1
3Oliver1
4Priya2
5QuinnNULL

Table checkouts

columntypeconstraints
checkout_idINTPRIMARY KEY
copy_idINTNOT NULL
member_idINTNOT NULL
checkout_dateDATENOT NULL
return_dateDATE
renew_countINTNOT NULL

Sample data:

checkout_datecheckout_idcopy_idmember_idrenew_countreturn_date
2025-05-011113NULL
2025-05-1022212025-05-20
2025-05-153311NULL
2025-05-054432NULL
2025-04-0155242025-04-10
2025-03-016615NULL
2025-01-01713102025-01-20
2025-02-10814212025-02-12
2025-03-0591531NULL
2025-01-01107222025-02-15

Table reservations

columntypeconstraints
reservation_idINTPRIMARY KEY
member_idINTNOT NULL
book_idINTNOT NULL
reserve_dateDATENOT NULL

Sample data:

book_idmember_idreservation_idreserve_date
1112025-05-01
1222025-05-02
2232025-05-03
2342025-05-04
3352025-05-05
4362025-05-06
1472025-05-07
2482025-05-08
3492025-05-09
21102025-05-10
32112025-05-11

Expected output

The single referred member whose reservation count differs the most from their referrer's count, with ties broken by the smallest member_id. Based on the sample data, members 2 and 3 both have an absolute difference of 1 versus referrer 1, so member 2 is chosen by the tie-break rule.

abs_diffmember_idreferrer_member_idreservations_mreservations_r
12132

Hints

  1. First aggregate reservations per member, then join members to this aggregation twice: once for the referred member and once for the referrer.
  2. 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.