Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit01e707c

Browse files
authored
Added task 3497
1 parentcd4d4dd commit01e707c

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
3497\. Analyze Subscription Conversion
2+
3+
Medium
4+
5+
Table:`UserActivity`
6+
7+
+------------------+---------+
8+
| Column Name | Type |
9+
+------------------+---------+
10+
| user_id | int |
11+
| activity_date | date |
12+
| activity_type | varchar |
13+
| activity_duration| int |
14+
+------------------+---------+
15+
(user_id, activity_date, activity_type) is the unique key for this table. activity_type is one of ('free_trial', 'paid', 'cancelled').
16+
activity_duration is the number of minutes the user spent on the platform that day.
17+
Each row represents a user's activity on a specific date.
18+
19+
A subscription service wants to analyze user behavior patterns. The company offers a`7`\-day**free trial**, after which users can subscribe to a**paid plan** or**cancel**. Write a solution to:
20+
21+
1. Find users who converted from free trial to paid subscription
22+
2. Calculate each user's**average daily activity duration** during their**free trial** period (rounded to`2` decimal places)
23+
3. Calculate each user's**average daily activity duration** during their**paid** subscription period (rounded to`2` decimal places)
24+
25+
Return_the result table ordered by_`user_id`_in**ascending** order_.
26+
27+
The result format is in the following example.
28+
29+
**Example:**
30+
31+
**Input:**
32+
33+
UserActivity table:
34+
35+
| user_id| activity_date| activity_type| activity_duration|
36+
|---------|---------------|---------------|-------------------|
37+
| 1| 2023-01-01| free_trial| 45|
38+
| 1| 2023-01-02| free_trial| 30|
39+
| 1| 2023-01-05| free_trial| 60|
40+
| 1| 2023-01-10| paid| 75|
41+
| 1| 2023-01-12| paid| 90|
42+
| 1| 2023-01-15| paid| 65|
43+
| 2| 2023-02-01| free_trial| 55|
44+
| 2| 2023-02-03| free_trial| 25|
45+
| 2| 2023-02-07| free_trial| 50|
46+
| 2| 2023-02-10| cancelled| 0|
47+
| 3| 2023-03-05| free_trial| 70|
48+
| 3| 2023-03-06| free_trial| 60|
49+
| 3| 2023-03-08| free_trial| 80|
50+
| 3| 2023-03-12| paid| 50|
51+
| 3| 2023-03-15| paid| 55|
52+
| 3| 2023-03-20| paid| 85|
53+
| 4| 2023-04-01| free_trial| 40|
54+
| 4| 2023-04-03| free_trial| 35|
55+
| 4| 2023-04-05| paid| 45|
56+
| 4| 2023-04-07| cancelled| 0|
57+
58+
**Output:**
59+
60+
| user_id| trial_avg_duration| paid_avg_duration|
61+
|---------|--------------------|-------------------|
62+
| 1| 45.00| 76.67|
63+
| 3| 70.00| 63.33|
64+
| 4| 37.50| 45.00|
65+
66+
**Explanation:**
67+
68+
***User 1:**
69+
* Had 3 days of free trial with durations of 45, 30, and 60 minutes.
70+
* Average trial duration: (45 + 30 + 60) / 3 = 45.00 minutes.
71+
* Had 3 days of paid subscription with durations of 75, 90, and 65 minutes.
72+
* Average paid duration: (75 + 90 + 65) / 3 = 76.67 minutes.
73+
***User 2:**
74+
* Had 3 days of free trial with durations of 55, 25, and 50 minutes.
75+
* Average trial duration: (55 + 25 + 50) / 3 = 43.33 minutes.
76+
* Did not convert to a paid subscription (only had free\_trial and cancelled activities).
77+
* Not included in the output because they didn't convert to paid.
78+
***User 3:**
79+
* Had 3 days of free trial with durations of 70, 60, and 80 minutes.
80+
* Average trial duration: (70 + 60 + 80) / 3 = 70.00 minutes.
81+
* Had 3 days of paid subscription with durations of 50, 55, and 85 minutes.
82+
* Average paid duration: (50 + 55 + 85) / 3 = 63.33 minutes.
83+
***User 4:**
84+
* Had 2 days of free trial with durations of 40 and 35 minutes.
85+
* Average trial duration: (40 + 35) / 2 = 37.50 minutes.
86+
* Had 1 day of paid subscription with duration of 45 minutes before cancelling.
87+
* Average paid duration: 45.00 minutes.
88+
89+
The result table only includes users who converted from free trial to paid subscription (users 1, 3, and 4), and is ordered by user\_id in ascending order.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Write your MySQL query statement below
2+
# #Medium #2025_03_29_Time_347_ms_(100.00%)_Space_0.0_MB_(100.00%)
3+
SELECT
4+
ft.user_id,
5+
ROUND(ft.avg_trial,2)AS trial_avg_duration,
6+
ROUND(pt.avg_paid,2)AS paid_avg_duration
7+
FROM
8+
(SELECT user_id,AVG(activity_duration)AS avg_trial
9+
FROM UserActivity
10+
WHERE activity_type='free_trial'
11+
GROUP BY user_id) ft
12+
JOIN
13+
(SELECT user_id,AVG(activity_duration)AS avg_paid
14+
FROM UserActivity
15+
WHERE activity_type='paid'
16+
GROUP BY user_id) pt
17+
ONft.user_id=pt.user_id
18+
ORDER BYft.user_idASC;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
packageg3401_3500.s3497_analyze_subscription_conversion;
2+
3+
importstaticorg.hamcrest.CoreMatchers.equalTo;
4+
importstaticorg.hamcrest.MatcherAssert.assertThat;
5+
6+
importjava.io.BufferedReader;
7+
importjava.io.FileNotFoundException;
8+
importjava.io.FileReader;
9+
importjava.sql.Connection;
10+
importjava.sql.ResultSet;
11+
importjava.sql.SQLException;
12+
importjava.sql.Statement;
13+
importjava.util.stream.Collectors;
14+
importjavax.sql.DataSource;
15+
importorg.junit.jupiter.api.Test;
16+
importorg.zapodot.junit.db.annotations.EmbeddedDatabase;
17+
importorg.zapodot.junit.db.annotations.EmbeddedDatabaseTest;
18+
importorg.zapodot.junit.db.common.CompatibilityMode;
19+
20+
@EmbeddedDatabaseTest(
21+
compatibilityMode =CompatibilityMode.MySQL,
22+
initialSqls =
23+
" CREATE TABLE UserActivity ("
24+
+" user_id INT,"
25+
+" activity_date date,"
26+
+" activity_type VARCHAR(100),"
27+
+" activity_duration INT"
28+
+");"
29+
+"INSERT INTO UserActivity (user_id, activity_date, activity_type, activity_duration)"
30+
+"VALUES"
31+
+" (1, '2023-01-01', 'free_trial', 45),"
32+
+" (1, '2023-01-02', 'free_trial', 30),"
33+
+" (1, '2023-01-05', 'free_trial', 60),"
34+
+" (1, '2023-01-10', 'paid', 75),"
35+
+" (1, '2023-01-12', 'paid', 90),"
36+
+" (1, '2023-01-15', 'paid', 65),"
37+
+" (2, '2023-02-01', 'free_trial', 55),"
38+
+" (2, '2023-02-03', 'free_trial', 25),"
39+
+" (2, '2023-02-07', 'free_trial', 50),"
40+
+" (2, '2023-02-10', 'cancelled', 0),"
41+
+" (3, '2023-03-05', 'free_trial', 70),"
42+
+" (3, '2023-03-06', 'free_trial', 60),"
43+
+" (3, '2023-03-08', 'free_trial', 80),"
44+
+" (3, '2023-03-12', 'paid', 50),"
45+
+" (3, '2023-03-15', 'paid', 55),"
46+
+" (3, '2023-03-20', 'paid', 85),"
47+
+" (4, '2023-04-01', 'free_trial', 40),"
48+
+" (4, '2023-04-03', 'free_trial', 35),"
49+
+" (4, '2023-04-05', 'paid', 45),"
50+
+" (4, '2023-04-07', 'cancelled', 0);")
51+
classMysqlTest {
52+
@Test
53+
voidtestScript(@EmbeddedDatabaseDataSourcedataSource)
54+
throwsSQLException,FileNotFoundException {
55+
try (finalConnectionconnection =dataSource.getConnection()) {
56+
try (finalStatementstatement =connection.createStatement();
57+
finalResultSetresultSet =
58+
statement.executeQuery(
59+
newBufferedReader(
60+
newFileReader(
61+
"src/main/java/g3401_3500/"
62+
+"s3497_analyze_subscription_conversion/"
63+
+"script.sql"))
64+
.lines()
65+
.collect(Collectors.joining("\n"))
66+
.replaceAll("#.*?\\r?\\n",""))) {
67+
checkRow(resultSet,newString[] {"1","45.0","76.67"});
68+
checkRow(resultSet,newString[] {"3","70.0","63.33"});
69+
checkRow(resultSet,newString[] {"4","37.5","45.0"});
70+
assertThat(resultSet.next(),equalTo(false));
71+
}
72+
}
73+
}
74+
75+
privatevoidcheckRow(ResultSetresultSet,String[]values)throwsSQLException {
76+
assertThat(resultSet.next(),equalTo(true));
77+
assertThat(resultSet.getNString(1),equalTo(values[0]));
78+
assertThat(resultSet.getNString(2),equalTo(values[1]));
79+
assertThat(resultSet.getNString(3),equalTo(values[2]));
80+
}
81+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp