Skip to content

Commit 8965365

Browse files
authored
Added task 3617
1 parent 7d191f6 commit 8965365

File tree

3 files changed

+327
-0
lines changed
  • src
    • main/java/g3601_3700/s3617_find_students_with_study_spiral_pattern
    • test/java/g3601_3700/s3617_find_students_with_study_spiral_pattern

3 files changed

+327
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
3617\. Find Students with Study Spiral Pattern
2+
3+
Hard
4+
5+
Table: `students`
6+
7+
+--------------+---------+
8+
| Column Name | Type |
9+
+--------------+---------+
10+
| student_id | int |
11+
| student_name | varchar |
12+
| major | varchar |
13+
+--------------+---------+
14+
student_id is the unique identifier for this table.
15+
Each row contains information about a student and their academic major.
16+
17+
Table: `study_sessions`
18+
19+
+---------------+---------+
20+
| Column Name | Type |
21+
+---------------+---------+
22+
| session_id | int |
23+
| student_id | int |
24+
| subject | varchar |
25+
| session_date | date |
26+
| hours_studied | decimal |
27+
+---------------+---------+
28+
session_id is the unique identifier for this table.
29+
Each row represents a study session by a student for a specific subject.
30+
31+
Write a solution to find students who follow the **Study Spiral Pattern** - students who consistently study multiple subjects in a rotating cycle.
32+
33+
* A Study Spiral Pattern means a student studies at least `3` **different subjects** in a repeating sequence
34+
* The pattern must repeat for **at least** `2` **complete cycles** (minimum `6` study sessions)
35+
* Sessions must be **consecutive dates** with no gaps longer than `2` days between sessions
36+
* Calculate the **cycle length** (number of different subjects in the pattern)
37+
* Calculate the **total study hours** across all sessions in the pattern
38+
* Only include students with cycle length of **at least** `3` **subjects**
39+
40+
Return _the result table ordered by cycle length in **descending** order, then by total study hours in **descending** order_.
41+
42+
The result format is in the following example.
43+
44+
**Example:**
45+
46+
**Input:**
47+
48+
students table:
49+
50+
| student_id | student_name | major |
51+
|------------|--------------|-------------------|
52+
| 1 | Alice Chen | Computer Science |
53+
| 2 | Bob Johnson | Mathematics |
54+
| 3 | Carol Davis | Physics |
55+
| 4 | David Wilson | Chemistry |
56+
| 5 | Emma Brown | Biology |
57+
58+
study\_sessions table:
59+
60+
| session_id | student_id | subject | session_date | hours_studied |
61+
|------------|------------|------------|--------------|----------------|
62+
| 1 | 1 | Math | 2023-10-01 | 2.5 |
63+
| 2 | 1 | Physics | 2023-10-02 | 3.0 |
64+
| 3 | 1 | Chemistry | 2023-10-03 | 2.0 |
65+
| 4 | 1 | Math | 2023-10-04 | 2.5 |
66+
| 5 | 1 | Physics | 2023-10-05 | 3.0 |
67+
| 6 | 1 | Chemistry | 2023-10-06 | 2.0 |
68+
| 7 | 2 | Algebra | 2023-10-01 | 4.0 |
69+
| 8 | 2 | Calculus | 2023-10-02 | 3.5 |
70+
| 9 | 2 | Statistics | 2023-10-03 | 2.5 |
71+
| 10 | 2 | Geometry | 2023-10-04 | 3.0 |
72+
| 11 | 2 | Algebra | 2023-10-05 | 4.0 |
73+
| 12 | 2 | Calculus | 2023-10-06 | 3.5 |
74+
| 13 | 2 | Statistics | 2023-10-07 | 2.5 |
75+
| 14 | 2 | Geometry | 2023-10-08 | 3.0 |
76+
| 15 | 3 | Biology | 2023-10-01 | 2.0 |
77+
| 16 | 3 | Chemistry | 2023-10-02 | 2.5 |
78+
| 17 | 3 | Biology | 2023-10-03 | 2.0 |
79+
| 18 | 3 | Chemistry | 2023-10-04 | 2.5 |
80+
| 19 | 4 | Organic | 2023-10-01 | 3.0 |
81+
| 20 | 4 | Physical | 2023-10-05 | 2.5 |
82+
83+
**Output:**
84+
85+
| student_id | student_name | major | cycle_length | total_study_hours |
86+
|------------|--------------|-------------------|--------------|-------------------|
87+
| 2 | Bob Johnson | Mathematics | 4 | 26.0 |
88+
| 1 | Alice Chen | Computer Science | 3 | 15.0 |
89+
90+
**Explanation:**
91+
92+
* **Alice Chen (student\_id = 1):**
93+
* Study sequence: Math → Physics → Chemistry → Math → Physics → Chemistry
94+
* Pattern: 3 subjects (Math, Physics, Chemistry) repeating for 2 complete cycles
95+
* Consecutive dates: Oct 1-6 with no gaps > 2 days
96+
* Cycle length: 3 subjects
97+
* Total hours: 2.5 + 3.0 + 2.0 + 2.5 + 3.0 + 2.0 = 15.0 hours
98+
* **Bob Johnson (student\_id = 2):**
99+
* Study sequence: Algebra → Calculus → Statistics → Geometry → Algebra → Calculus → Statistics → Geometry
100+
* Pattern: 4 subjects (Algebra, Calculus, Statistics, Geometry) repeating for 2 complete cycles
101+
* Consecutive dates: Oct 1-8 with no gaps > 2 days
102+
* Cycle length: 4 subjects
103+
* Total hours: 4.0 + 3.5 + 2.5 + 3.0 + 4.0 + 3.5 + 2.5 + 3.0 = 26.0 hours
104+
* **Students not included:**
105+
* Carol Davis (student\_id = 3): Only 2 subjects (Biology, Chemistry) - doesn't meet minimum 3 subjects requirement
106+
* David Wilson (student\_id = 4): Only 2 study sessions with a 4-day gap - doesn't meet consecutive dates requirement
107+
* Emma Brown (student\_id = 5): No study sessions recorded
108+
109+
The result table is ordered by cycle\_length in descending order, then by total\_study\_hours in descending order.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Write your MySQL query statement below
2+
# #Hard #Database #2025_07_16_Time_553_ms_(100.00%)_Space_0.0_MB_(100.00%)
3+
-- WITH studentstudysummary AS (
4+
-- SELECT
5+
-- student_id,
6+
-- SUM(hours_studied) AS total_study_hours,
7+
-- COUNT(DISTINCT subject) AS cycle_length
8+
-- FROM
9+
-- study_sessions
10+
-- GROUP BY
11+
-- student_id
12+
-- HAVING
13+
-- COUNT(DISTINCT subject) >= 3
14+
-- ),
15+
-- rankedstudysessionswithgaps AS (
16+
-- SELECT
17+
-- ss.student_id,
18+
-- ss.subject,
19+
-- ss.session_date,
20+
-- DATEDIFF(
21+
-- LEAD(ss.session_date, 1, ss.session_date)
22+
-- OVER (PARTITION BY ss.student_id ORDER BY ss.session_date),
23+
-- ss.session_date
24+
-- ) AS gap_to_next_session,
25+
-- ROW_NUMBER() OVER (PARTITION BY ss.student_id ORDER BY ss.session_date) AS rn,
26+
-- sss.total_study_hours,
27+
-- sss.cycle_length
28+
-- FROM
29+
-- study_sessions ss
30+
-- INNER JOIN studentstudysummary sss
31+
-- ON ss.student_id = sss.student_id
32+
-- ),
33+
-- cyclicstudents AS (
34+
-- SELECT
35+
-- rss1.student_id,
36+
-- rss1.cycle_length,
37+
-- rss1.total_study_hours
38+
-- FROM
39+
-- rankedstudysessionswithgaps rss1
40+
-- INNER JOIN rankedstudysessionswithgaps rss2
41+
-- ON rss1.student_id = rss2.student_id
42+
-- AND rss2.rn = rss1.rn + rss1.cycle_length
43+
-- AND rss1.subject = rss2.subject
44+
-- WHERE
45+
-- rss1.gap_to_next_session < 3
46+
-- AND rss2.gap_to_next_session < 3
47+
-- GROUP BY
48+
-- rss1.student_id,
49+
-- rss1.cycle_length,
50+
-- rss1.total_study_hours
51+
-- HAVING
52+
-- COUNT(DISTINCT rss1.subject) >= 3
53+
-- )
54+
-- SELECT
55+
-- s.student_id,
56+
-- s.student_name,
57+
-- s.major,
58+
-- cs.cycle_length,
59+
-- cs.total_study_hours
60+
-- FROM
61+
-- cyclicstudents cs
62+
-- INNER JOIN students s
63+
-- ON cs.student_id = s.student_id
64+
-- ORDER BY
65+
-- cs.cycle_length DESC,
66+
-- cs.total_study_hours DESC;
67+
WITH studentstudysummary AS (
68+
SELECT
69+
student_id,
70+
SUM(hours_studied) AS total_study_hours,
71+
COUNT(DISTINCT subject) AS cycle_length
72+
FROM study_sessions
73+
GROUP BY student_id
74+
HAVING COUNT(DISTINCT subject) >= 3
75+
),
76+
rankedstudysessionswithgaps AS (
77+
SELECT
78+
ss.student_id,
79+
ss.subject,
80+
ss.session_date,
81+
DATEDIFF('DAY',
82+
ss.session_date,
83+
LEAD(ss.session_date, 1, ss.session_date) OVER (
84+
PARTITION BY ss.student_id ORDER BY ss.session_date
85+
)
86+
) AS gap_to_next_session,
87+
ROW_NUMBER() OVER (PARTITION BY ss.student_id ORDER BY ss.session_date) AS rn,
88+
sss.total_study_hours,
89+
sss.cycle_length
90+
FROM study_sessions ss
91+
INNER JOIN studentstudysummary sss
92+
ON ss.student_id = sss.student_id
93+
),
94+
cyclicstudents AS (
95+
SELECT
96+
rss1.student_id,
97+
rss1.cycle_length,
98+
rss1.total_study_hours
99+
FROM rankedstudysessionswithgaps rss1
100+
INNER JOIN rankedstudysessionswithgaps rss2
101+
ON rss1.student_id = rss2.student_id
102+
AND rss2.rn = rss1.rn + rss1.cycle_length
103+
AND rss1.subject = rss2.subject
104+
WHERE
105+
rss1.gap_to_next_session < 3
106+
AND rss2.gap_to_next_session < 3
107+
GROUP BY
108+
rss1.student_id,
109+
rss1.cycle_length,
110+
rss1.total_study_hours
111+
HAVING
112+
COUNT(DISTINCT rss1.subject) >= 3
113+
)
114+
SELECT
115+
s.student_id,
116+
s.student_name,
117+
s.major,
118+
cs.cycle_length,
119+
cs.total_study_hours
120+
FROM cyclicstudents cs
121+
INNER JOIN students s ON cs.student_id = s.student_id
122+
ORDER BY cs.cycle_length DESC, cs.total_study_hours DESC;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package g3601_3700.s3617_find_students_with_study_spiral_pattern;
2+
3+
import static org.hamcrest.CoreMatchers.equalTo;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
6+
import java.io.BufferedReader;
7+
import java.io.FileNotFoundException;
8+
import java.io.FileReader;
9+
import java.sql.Connection;
10+
import java.sql.ResultSet;
11+
import java.sql.SQLException;
12+
import java.sql.Statement;
13+
import java.util.stream.Collectors;
14+
import javax.sql.DataSource;
15+
import org.junit.jupiter.api.Test;
16+
import org.zapodot.junit.db.annotations.EmbeddedDatabase;
17+
import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest;
18+
import org.zapodot.junit.db.common.CompatibilityMode;
19+
20+
@EmbeddedDatabaseTest(
21+
compatibilityMode = CompatibilityMode.MySQL,
22+
initialSqls =
23+
"CREATE TABLE students ("
24+
+ " student_id INT PRIMARY KEY,"
25+
+ " student_name VARCHAR(50),"
26+
+ " major VARCHAR(50)"
27+
+ ");"
28+
+ "INSERT INTO students (student_id, student_name, major) VALUES"
29+
+ "(1, 'Alice Chen', 'Computer Science'),"
30+
+ "(2, 'Bob Johnson', 'Mathematics'),"
31+
+ "(3, 'Carol Davis', 'Physics'),"
32+
+ "(4, 'David Wilson', 'Chemistry'),"
33+
+ "(5, 'Emma Brown', 'Biology');"
34+
+ "CREATE TABLE study_sessions ("
35+
+ " session_id INT PRIMARY KEY,"
36+
+ " student_id INT,"
37+
+ " subject VARCHAR(30),"
38+
+ " session_date DATE,"
39+
+ " hours_studied DECIMAL(3,1)"
40+
+ ");"
41+
+ "INSERT INTO study_sessions (session_id, student_id, "
42+
+ "subject, session_date, hours_studied) VALUES"
43+
+ "(1, 1, 'Math', '2023-10-01', 2.5),"
44+
+ "(2, 1, 'Physics', '2023-10-02', 3.0),"
45+
+ "(3, 1, 'Chemistry', '2023-10-03', 2.0),"
46+
+ "(4, 1, 'Math', '2023-10-04', 2.5),"
47+
+ "(5, 1, 'Physics', '2023-10-05', 3.0),"
48+
+ "(6, 1, 'Chemistry', '2023-10-06', 2.0),"
49+
+ "(7, 2, 'Algebra', '2023-10-01', 4.0),"
50+
+ "(8, 2, 'Calculus', '2023-10-02', 3.5),"
51+
+ "(9, 2, 'Statistics', '2023-10-03', 2.5),"
52+
+ "(10, 2, 'Geometry', '2023-10-04', 3.0),"
53+
+ "(11, 2, 'Algebra', '2023-10-05', 4.0),"
54+
+ "(12, 2, 'Calculus', '2023-10-06', 3.5),"
55+
+ "(13, 2, 'Statistics','2023-10-07', 2.5),"
56+
+ "(14, 2, 'Geometry', '2023-10-08', 3.0),"
57+
+ "(15, 3, 'Biology', '2023-10-01', 2.0),"
58+
+ "(16, 3, 'Chemistry', '2023-10-02', 2.5),"
59+
+ "(17, 3, 'Biology', '2023-10-03', 2.0),"
60+
+ "(18, 3, 'Chemistry', '2023-10-04', 2.5),"
61+
+ "(19, 4, 'Organic', '2023-10-01', 3.0),"
62+
+ "(20, 4, 'Physical', '2023-10-05', 2.5);")
63+
class MysqlTest {
64+
@Test
65+
void testScript(@EmbeddedDatabase DataSource dataSource)
66+
throws SQLException, FileNotFoundException {
67+
try (final Connection connection = dataSource.getConnection()) {
68+
try (final Statement statement = connection.createStatement();
69+
final ResultSet resultSet =
70+
statement.executeQuery(
71+
new BufferedReader(
72+
new FileReader(
73+
"src/main/java/g3601_3700/"
74+
+ "s3617_find_students_with_"
75+
+ "study_spiral_pattern/"
76+
+ "script.sql"))
77+
.lines()
78+
.collect(Collectors.joining("\n"))
79+
.replaceAll("#.*?\\r?\\n", ""))) {
80+
assertThat(resultSet.next(), equalTo(true));
81+
assertThat(resultSet.getNString(1), equalTo("2"));
82+
assertThat(resultSet.getNString(2), equalTo("Bob Johnson"));
83+
assertThat(resultSet.getNString(3), equalTo("Mathematics"));
84+
assertThat(resultSet.getNString(4), equalTo("4"));
85+
assertThat(resultSet.getNString(5), equalTo("26.0"));
86+
assertThat(resultSet.next(), equalTo(true));
87+
assertThat(resultSet.getNString(1), equalTo("1"));
88+
assertThat(resultSet.getNString(2), equalTo("Alice Chen"));
89+
assertThat(resultSet.getNString(3), equalTo("Computer Science"));
90+
assertThat(resultSet.getNString(4), equalTo("3"));
91+
assertThat(resultSet.getNString(5), equalTo("15.0"));
92+
assertThat(resultSet.next(), equalTo(false));
93+
}
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy