Skip to content

Added task 3586 #1997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions src/main/java/g3501_3600/s3586_find_covid_recovery_patients/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
3586\. Find COVID Recovery Patients

Medium

Table: `patients`

+-------------+---------+
| Column Name | Type |
+-------------+---------+
| patient_id | int |
| patient_name| varchar |
| age | int |
+-------------+---------+
patient_id is the unique identifier for this table.
Each row contains information about a patient.

Table: `covid_tests`

+-------------+---------+
| Column Name | Type |
+-------------+---------+
| test_id | int |
| patient_id | int |
| test_date | date |
| result | varchar |
+-------------+---------+
test_id is the unique identifier for this table.
Each row represents a COVID test result. The result can be Positive, Negative, or Inconclusive.

Write a solution to find patients who have **recovered from COVID** - patients who tested positive but later tested negative.

* A patient is considered recovered if they have **at least one** **Positive** test followed by at least one **Negative** test on a **later date**
* Calculate the **recovery time** in days as the **difference** between the **first positive test** and the **first negative test** after that **positive test**
* **Only include** patients who have both positive and negative test results

Return _the result table ordered by_ `recovery_time` _in **ascending** order, then by_ `patient_name` _in **ascending** order_.

The result format is in the following example.

**Example:**

**Input:**

patients table:

+------------+--------------+-----+
| patient_id | patient_name | age |
+------------+--------------+-----+
| 1 | Alice Smith | 28 |
| 2 | Bob Johnson | 35 |
| 3 | Carol Davis | 42 |
| 4 | David Wilson | 31 |
| 5 | Emma Brown | 29 |
+------------+--------------+-----+

covid\_tests table:

+---------+------------+------------+--------------+
| test_id | patient_id | test_date | result |
|---------|------------|------------|--------------|
| 1 | 1 | 2023-01-15 | Positive |
| 2 | 1 | 2023-01-25 | Negative |
| 3 | 2 | 2023-02-01 | Positive |
| 4 | 2 | 2023-02-05 | Inconclusive |
| 5 | 2 | 2023-02-12 | Negative |
| 6 | 3 | 2023-01-20 | Negative |
| 7 | 3 | 2023-02-10 | Positive |
| 8 | 3 | 2023-02-20 | Negative |
| 9 | 4 | 2023-01-10 | Positive |
| 10 | 4 | 2023-01-18 | Positive |
| 11 | 5 | 2023-02-15 | Negative |
| 12 | 5 | 2023-02-20 | Negative |
+---------+------------+------------+--------------+

**Output:**

+------------+--------------+-----+---------------+
| patient_id | patient_name | age | recovery_time |
|------------|--------------|-----|---------------|
| 1 | Alice Smith | 28 | 10 |
| 3 | Carol Davis | 42 | 10 |
| 2 | Bob Johnson | 35 | 11 |
+------------+--------------+-----+---------------+

**Explanation:**

* **Alice Smith (patient\_id = 1):**
* First positive test: 2023-01-15
* First negative test after positive: 2023-01-25
* Recovery time: 25 - 15 = 10 days
* **Bob Johnson (patient\_id = 2):**
* First positive test: 2023-02-01
* Inconclusive test on 2023-02-05 (ignored for recovery calculation)
* First negative test after positive: 2023-02-12
* Recovery time: 12 - 1 = 11 days
* **Carol Davis (patient\_id = 3):**
* Had negative test on 2023-01-20 (before positive test)
* First positive test: 2023-02-10
* First negative test after positive: 2023-02-20
* Recovery time: 20 - 10 = 10 days
* **Patients not included:**
* David Wilson (patient\_id = 4): Only has positive tests, no negative test after positive
* Emma Brown (patient\_id = 5): Only has negative tests, never tested positive

Output table is ordered by recovery\_time in ascending order, and then by patient\_name in ascending order.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Write your MySQL query statement below
# #Medium #Database #2025_06_19_Time_471_ms_(97.17%)_Space_0.0_MB_(100.00%)
-- mysql
-- SELECT
-- p.patient_id,
-- p.patient_name,
-- p.age,
-- DATEDIFF(
-- min(neg.test_date),
-- min(pos.test_date)
-- ) AS recovery_time
-- FROM
-- patients p
-- JOIN covid_tests pos ON
-- p.patient_id = pos.patient_id AND pos.result = 'Positive'
-- JOIN covid_tests neg ON
-- p.patient_id = neg.patient_id AND neg.result = 'Negative'
-- WHERE
-- neg.test_date > pos.test_date
-- GROUP BY
-- p.patient_id, p.patient_name, p.age
-- ORDER BY
-- recovery_time, p.patient_name;
select
p.patient_id,
p.patient_name,
p.age,
datediff(
day,
pos.first_pos_date,
neg.first_neg_date
) as recovery_time
from
patients p
join (
select patient_id, min(test_date) as first_pos_date
from covid_tests
where result = 'Positive'
group by patient_id
) pos on p.patient_id = pos.patient_id
join (
select
c1.patient_id,
min(c1.test_date) as first_neg_date
from
covid_tests c1
join (
select patient_id, min(test_date) as first_pos_date
from covid_tests
where result = 'Positive'
group by patient_id
) p2 on c1.patient_id = p2.patient_id
where
c1.result = 'Negative'
and c1.test_date > p2.first_pos_date
group by c1.patient_id
) neg on p.patient_id = neg.patient_id
order by
recovery_time ASC, p.patient_name ASC;
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package g3501_3600.s3586_find_covid_recovery_patients;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.zapodot.junit.db.annotations.EmbeddedDatabase;
import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest;
import org.zapodot.junit.db.common.CompatibilityMode;

@EmbeddedDatabaseTest(
compatibilityMode = CompatibilityMode.MySQL,
initialSqls =
"CREATE TABLE patients (patient_id INTEGER, patient_name VARCHAR(255), age INTEGER); "
+ "INSERT INTO patients (patient_id, patient_name, age) VALUES"
+ "(1, 'Alice Smith', 28),"
+ "(2, 'Bob Johnson', 35),"
+ "(3, 'Carol Davis', 42),"
+ "(4, 'David Wilson', 31),"
+ "(5, 'Emma Brown', 29);"
+ "CREATE TABLE covid_tests (test_id INTEGER, patient_id INTEGER"
+ ", test_date DATE, result VARCHAR(255)); "
+ "INSERT INTO covid_tests (test_id, patient_id, test_date, result) VALUES"
+ "(1, 1, '2023-01-15', 'Positive'),"
+ "(2, 1, '2023-01-25', 'Negative'),"
+ "(3, 2, '2023-02-01', 'Positive'),"
+ "(4, 2, '2023-02-05', 'Inconclusive'),"
+ "(5, 2, '2023-02-12', 'Negative'),"
+ "(6, 3, '2023-01-20', 'Negative'),"
+ "(7, 3, '2023-02-10', 'Positive'),"
+ "(8, 3, '2023-02-20', 'Negative'),"
+ "(9, 4, '2023-01-10', 'Positive'),"
+ "(10, 4, '2023-01-18', 'Positive'),"
+ "(11, 5, '2023-02-15', 'Negative'),"
+ "(12, 5, '2023-02-20', 'Negative');")
class MysqlTest {
@Test
void testScript(@EmbeddedDatabase DataSource dataSource)
throws SQLException, FileNotFoundException {
try (final Connection connection = dataSource.getConnection()) {
try (final Statement statement = connection.createStatement();
final ResultSet resultSet =
statement.executeQuery(
new BufferedReader(
new FileReader(
"src/main/java/g3501_3600/"
+ "s3586_find_covid_recovery_patients/"
+ "script.sql"))
.lines()
.collect(Collectors.joining("\n"))
.replaceAll("#.*?\\r?\\n", ""))) {
assertThat(resultSet.next(), equalTo(true));
assertThat(resultSet.getNString(1), equalTo("1"));
assertThat(resultSet.getNString(2), equalTo("Alice Smith"));
assertThat(resultSet.getNString(3), equalTo("28"));
assertThat(resultSet.getNString(4), equalTo("10"));
assertThat(resultSet.next(), equalTo(true));
assertThat(resultSet.getNString(1), equalTo("3"));
assertThat(resultSet.getNString(2), equalTo("Carol Davis"));
assertThat(resultSet.getNString(3), equalTo("42"));
assertThat(resultSet.getNString(4), equalTo("10"));
assertThat(resultSet.next(), equalTo(true));
assertThat(resultSet.getNString(1), equalTo("2"));
assertThat(resultSet.getNString(2), equalTo("Bob Johnson"));
assertThat(resultSet.getNString(3), equalTo("35"));
assertThat(resultSet.getNString(4), equalTo("11"));
assertThat(resultSet.next(), equalTo(false));
}
}
}
}