|
| 1 | +/* |
| 2 | +Write a query to return the number of fast movie watchers vs slow movie watchers. |
| 3 | +fast movie watcher: by average return their rentals within 5 days. |
| 4 | +slow movie watcher: takes an average of >5 days to return their rentals. |
| 5 | +Most customers have multiple rentals over time, you need to first compute the number of days for each rental transaction, then compute the average on the rounded up days. e.g., if the rental period is 1 day and 10 hours, count it as 2 days. |
| 6 | +Skip the rentals that have not been returned yet, e.g., rental_ts IS NULL. |
| 7 | +The orders of your results doesn't matter. |
| 8 | +A customer can only rent one movie per transaction. |
| 9 | +
|
| 10 | +
|
| 11 | +*/ |
| 12 | +-- this is my wrong solution, it's cuz i calculated the num of days and duration wrong way! |
| 13 | + |
| 14 | + |
| 15 | +with h as ( |
| 16 | +select |
| 17 | +customer_id, |
| 18 | +rental_id, |
| 19 | +DATE_PART('hour', AGE( return_ts, rental_ts)) AS hours, |
| 20 | +DATE_PART('day', AGE( return_ts, rental_ts)) AS days |
| 21 | +from rental |
| 22 | +where return_ts is not null ), |
| 23 | + |
| 24 | +h2 as ( |
| 25 | +select |
| 26 | +rental_id, |
| 27 | +customer_id, |
| 28 | +hours, days, |
| 29 | +case when hours > 0 then days+1 else days end as rounded_days |
| 30 | +from h), |
| 31 | + |
| 32 | + |
| 33 | +h3 as ( |
| 34 | +select customer_id, round(avg(rounded_days)) as d from h2 |
| 35 | +group by customer_id), |
| 36 | + |
| 37 | +h4 as ( |
| 38 | +select |
| 39 | + CASE WHEN d <= 5 THEN 'fast_watcher' |
| 40 | + when d > 5 then 'slow watcher' end as tip |
| 41 | + |
| 42 | +from h3) |
| 43 | + |
| 44 | +select tip as watcher_category , count(*) from h4 |
| 45 | +group by tip |
| 46 | + |
| 47 | + |
| 48 | +-- my working solution - after looking up |
| 49 | + |
| 50 | +with h as ( |
| 51 | +select |
| 52 | +customer_id, |
| 53 | +rental_id, |
| 54 | + extract(days from age(return_ts, rental_ts))+1 as avg_days |
| 55 | +from rental |
| 56 | +where return_ts is not null ), |
| 57 | + |
| 58 | +h2 as( |
| 59 | + |
| 60 | +select customer_id, avg(avg_days) as total |
| 61 | +from h |
| 62 | +group by customer_id) |
| 63 | + |
| 64 | + |
| 65 | +select watcher_category, count(*) from ( |
| 66 | +select |
| 67 | +customer_id, |
| 68 | +case when total > 5 then 'slow_watcher' |
| 69 | + when total <=5 then 'fast_watcher' end as watcher_category |
| 70 | + |
| 71 | +from h2)k |
| 72 | +group by watcher_category |
| 73 | + |
| 74 | +-- official solution |
| 75 | +WITH average_rental_days AS ( |
| 76 | + SELECT |
| 77 | + customer_id, |
| 78 | + AVG(EXTRACT(days FROM (return_ts - rental_ts) ) + 1) AS average_days |
| 79 | + FROM rental |
| 80 | + WHERE return_ts IS NOT NULL |
| 81 | + GROUP BY 1 |
| 82 | +) |
| 83 | +SELECT CASE WHEN average_days <= 5 THEN 'fast_watcher' |
| 84 | + WHEN average_days > 5 THEN 'slow_watcher' |
| 85 | + ELSE NULL |
| 86 | + END AS watcher_category, |
| 87 | + COUNT(*) |
| 88 | +FROM average_rental_days |
| 89 | +GROUP BY watcher_category; |
| 90 | + |
| 91 | + |
0 commit comments