Unpopular Books - Problem
Library Sales Analysis Challenge

You're working as a data analyst for a major bookstore chain and need to identify underperforming books that should be considered for removal from inventory.

The Challenge:
Find all books that have sold less than 10 copies in the past year (from 2018-06-23 to 2019-06-23), but only consider books that have been available for at least one month (available before 2019-05-23).

Database Schema:
Books table contains book information including when each book became available.
Orders table tracks all book sales with quantities and dispatch dates.

Key Rules:
• Today's date is 2019-06-23
• "Last year" means from 2018-06-23 to 2019-06-23
• Books must be available before 2019-05-23 (at least 1 month old)
• Count total quantity sold, not number of orders
• Books with no sales at all in the period also qualify as unpopular

Input & Output

example_1.sql — Basic Case
$ Input: Books: [(1,'Book1','2019-01-01'), (2,'Book2','2019-04-01'), (3,'Book3','2019-06-01')]\nOrders: [(1,1,5,'2019-01-15'), (2,1,3,'2019-02-10'), (3,2,15,'2019-05-01')]
Output: [{'book_id': 1, 'name': 'Book1'}]
💡 Note: Book1 sold 8 copies (5+3) which is < 10. Book2 sold 15 copies so excluded. Book3 is too new (available 2019-06-01, less than 1 month old).
example_2.sql — No Sales Case
$ Input: Books: [(1,'OldBook','2019-01-01'), (2,'NewBook','2019-06-01')]\nOrders: []
Output: [{'book_id': 1, 'name': 'OldBook'}]
💡 Note: OldBook has 0 sales (< 10) and is old enough. NewBook is excluded due to being too new (less than 1 month available).
example_3.sql — Edge Case
$ Input: Books: [(1,'PopularBook','2019-01-01'), (2,'UnpopularBook','2019-02-01')]\nOrders: [(1,1,10,'2019-03-01'), (2,2,9,'2019-04-01')]
Output: [{'book_id': 2, 'name': 'UnpopularBook'}]
💡 Note: PopularBook sold exactly 10 copies (not < 10). UnpopularBook sold 9 copies (< 10) and qualifies as unpopular.

Visualization

Tap to expand
📚 Bookstore Sales Analysis📅 Time FilterToday: 2019-06-23Sales Period:2018-06-23 to 2019-06-23Book Age Cutoff:Available before 2019-05-23(at least 1 month old)🔍 Analysis Process1. LEFT JOIN Books + Orders2. Filter by dates3. GROUP BY book_id4. SUM(quantity) per book5. HAVING sales < 10📊 ResultsUnpopular Books:• Books with 0-9 total sales• Available ≥ 1 monthAction:• Consider for clearance• Remove from inventory💡 Key InsightsLEFT JOIN Importance:• Ensures books with ZERO sales are included in results• INNER JOIN would miss books that never sold anythingPerformance Optimization:• Single query vs N+1 queries (brute force)• Database handles aggregation efficiently with GROUP BY
Understanding the Visualization
1
Identify Eligible Books
Books available before 2019-05-23 (at least 1 month old)
2
Count Sales
Sum all quantities sold between 2018-06-23 and 2019-06-23
3
Filter Unpopular
Keep only books with total sales less than 10 copies
Key Takeaway
🎯 Key Insight: LEFT JOIN is crucial for including books with zero sales, while proper date filtering and aggregation in a single query provides optimal performance for large datasets.

Time & Space Complexity

Time Complexity
⏱️
O(N + M)

Single pass through Books (N) and Orders (M) tables with database optimization

n
2n
Linear Growth
Space Complexity
O(1)

No additional space needed - database handles aggregation internally

n
2n
Linear Space

Constraints

  • 1 ≤ book_id ≤ 104
  • 1 ≤ order_id ≤ 104
  • 1 ≤ quantity ≤ 100
  • All dates are in 'YYYY-MM-DD' format
  • Today's date is fixed as 2019-06-23
  • Book names are unique varchar strings up to 255 characters
Asked in
Amazon 45 Google 32 Microsoft 28 Meta 18
41.2K Views
Medium-High Frequency
~15 min Avg. Time
1.8K Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen