Skip to content

Commit 31a2a5b

Browse files
authored
Create fast_movie_watchers_vs_slow_watchers.sql
1 parent 4d187b2 commit 31a2a5b

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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

Comments
 (0)