Skip to content

Commit 53d1406

Browse files
authored
feat: add solutions to lc problem: No.3586 (#4499)
No.3586.Find COVID Recovery Patients
1 parent e68e1fd commit 53d1406

File tree

4 files changed

+200
-2
lines changed

4 files changed

+200
-2
lines changed

solution/3500-3599/3586.Find COVID Recovery Patients/README.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,82 @@ Each row represents a COVID test result. The result can be Positive, Negative, o
155155

156156
<!-- solution:start -->
157157

158-
### 方法一
158+
### 方法一:分组统计 + 等值连接
159+
160+
我们可以先找出每个患者的第一次阳性检测日期,记录在表 `first_positive` 中。接着,我们可以在 `covid_tests` 表中找到每个患者在第一次阳性检测之后的第一次阴性检测日期,记录在表 `first_negative_after_positive` 中。最后,我们将这两个表与 `patients` 表连接,计算恢复时间,并按照要求排序。
159161

160162
<!-- tabs:start -->
161163

162164
#### MySQL
163165

164166
```sql
167+
# Write your MySQL query statement below
168+
WITH
169+
first_positive AS (
170+
SELECT
171+
patient_id,
172+
MIN(test_date) AS first_positive_date
173+
FROM covid_tests
174+
WHERE result = 'Positive'
175+
GROUP BY patient_id
176+
),
177+
first_negative_after_positive AS (
178+
SELECT
179+
t.patient_id,
180+
MIN(t.test_date) AS first_negative_date
181+
FROM
182+
covid_tests t
183+
JOIN first_positive p
184+
ON t.patient_id = p.patient_id AND t.test_date > p.first_positive_date
185+
WHERE t.result = 'Negative'
186+
GROUP BY t.patient_id
187+
)
188+
SELECT
189+
p.patient_id,
190+
p.patient_name,
191+
p.age,
192+
DATEDIFF(n.first_negative_date, f.first_positive_date) AS recovery_time
193+
FROM
194+
first_positive f
195+
JOIN first_negative_after_positive n ON f.patient_id = n.patient_id
196+
JOIN patients p ON p.patient_id = f.patient_id
197+
ORDER BY recovery_time ASC, patient_name ASC;
198+
```
199+
200+
#### Pandas
201+
202+
```python
203+
import pandas as pd
204+
205+
206+
def find_covid_recovery_patients(
207+
patients: pd.DataFrame, covid_tests: pd.DataFrame
208+
) -> pd.DataFrame:
209+
covid_tests["test_date"] = pd.to_datetime(covid_tests["test_date"])
210+
211+
pos = (
212+
covid_tests[covid_tests["result"] == "Positive"]
213+
.groupby("patient_id", as_index=False)["test_date"]
214+
.min()
215+
)
216+
pos.rename(columns={"test_date": "first_positive_date"}, inplace=True)
217+
218+
neg = covid_tests.merge(pos, on="patient_id")
219+
neg = neg[
220+
(neg["result"] == "Negative") & (neg["test_date"] > neg["first_positive_date"])
221+
]
222+
neg = neg.groupby("patient_id", as_index=False)["test_date"].min()
223+
neg.rename(columns={"test_date": "first_negative_date"}, inplace=True)
224+
225+
df = pos.merge(neg, on="patient_id")
226+
df["recovery_time"] = (
227+
df["first_negative_date"] - df["first_positive_date"]
228+
).dt.days
165229

230+
out = df.merge(patients, on="patient_id")[
231+
["patient_id", "patient_name", "age", "recovery_time"]
232+
]
233+
return out.sort_values(by=["recovery_time", "patient_name"]).reset_index(drop=True)
166234
```
167235

168236
<!-- tabs:end -->

solution/3500-3599/3586.Find COVID Recovery Patients/README_EN.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,82 @@ Each row represents a COVID test result. The result can be Positive, Negative, o
155155

156156
<!-- solution:start -->
157157

158-
### Solution 1
158+
### Solution 1: Group Statistics + Equi-join
159+
160+
We can first find the date of the first positive test for each patient and record this in table first_positive. Next, we can find the date of the first negative test for each patient after their first positive test in the covid_tests table, and record this in table first_negative_after_positive. Finally, we join these two tables with the patients table, calculate the recovery time, and sort according to requirements.
159161

160162
<!-- tabs:start -->
161163

162164
#### MySQL
163165

164166
```sql
167+
# Write your MySQL query statement below
168+
WITH
169+
first_positive AS (
170+
SELECT
171+
patient_id,
172+
MIN(test_date) AS first_positive_date
173+
FROM covid_tests
174+
WHERE result = 'Positive'
175+
GROUP BY patient_id
176+
),
177+
first_negative_after_positive AS (
178+
SELECT
179+
t.patient_id,
180+
MIN(t.test_date) AS first_negative_date
181+
FROM
182+
covid_tests t
183+
JOIN first_positive p
184+
ON t.patient_id = p.patient_id AND t.test_date > p.first_positive_date
185+
WHERE t.result = 'Negative'
186+
GROUP BY t.patient_id
187+
)
188+
SELECT
189+
p.patient_id,
190+
p.patient_name,
191+
p.age,
192+
DATEDIFF(n.first_negative_date, f.first_positive_date) AS recovery_time
193+
FROM
194+
first_positive f
195+
JOIN first_negative_after_positive n ON f.patient_id = n.patient_id
196+
JOIN patients p ON p.patient_id = f.patient_id
197+
ORDER BY recovery_time ASC, patient_name ASC;
198+
```
199+
200+
#### Pandas
201+
202+
```python
203+
import pandas as pd
204+
205+
206+
def find_covid_recovery_patients(
207+
patients: pd.DataFrame, covid_tests: pd.DataFrame
208+
) -> pd.DataFrame:
209+
covid_tests["test_date"] = pd.to_datetime(covid_tests["test_date"])
210+
211+
pos = (
212+
covid_tests[covid_tests["result"] == "Positive"]
213+
.groupby("patient_id", as_index=False)["test_date"]
214+
.min()
215+
)
216+
pos.rename(columns={"test_date": "first_positive_date"}, inplace=True)
217+
218+
neg = covid_tests.merge(pos, on="patient_id")
219+
neg = neg[
220+
(neg["result"] == "Negative") & (neg["test_date"] > neg["first_positive_date"])
221+
]
222+
neg = neg.groupby("patient_id", as_index=False)["test_date"].min()
223+
neg.rename(columns={"test_date": "first_negative_date"}, inplace=True)
224+
225+
df = pos.merge(neg, on="patient_id")
226+
df["recovery_time"] = (
227+
df["first_negative_date"] - df["first_positive_date"]
228+
).dt.days
165229

230+
out = df.merge(patients, on="patient_id")[
231+
["patient_id", "patient_name", "age", "recovery_time"]
232+
]
233+
return out.sort_values(by=["recovery_time", "patient_name"]).reset_index(drop=True)
166234
```
167235

168236
<!-- tabs:end -->
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import pandas as pd
2+
3+
4+
def find_covid_recovery_patients(
5+
patients: pd.DataFrame, covid_tests: pd.DataFrame
6+
) -> pd.DataFrame:
7+
covid_tests["test_date"] = pd.to_datetime(covid_tests["test_date"])
8+
9+
pos = (
10+
covid_tests[covid_tests["result"] == "Positive"]
11+
.groupby("patient_id", as_index=False)["test_date"]
12+
.min()
13+
)
14+
pos.rename(columns={"test_date": "first_positive_date"}, inplace=True)
15+
16+
neg = covid_tests.merge(pos, on="patient_id")
17+
neg = neg[
18+
(neg["result"] == "Negative") & (neg["test_date"] > neg["first_positive_date"])
19+
]
20+
neg = neg.groupby("patient_id", as_index=False)["test_date"].min()
21+
neg.rename(columns={"test_date": "first_negative_date"}, inplace=True)
22+
23+
df = pos.merge(neg, on="patient_id")
24+
df["recovery_time"] = (
25+
df["first_negative_date"] - df["first_positive_date"]
26+
).dt.days
27+
28+
out = df.merge(patients, on="patient_id")[
29+
["patient_id", "patient_name", "age", "recovery_time"]
30+
]
31+
return out.sort_values(by=["recovery_time", "patient_name"]).reset_index(drop=True)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Write your MySQL query statement below
2+
WITH
3+
first_positive AS (
4+
SELECT
5+
patient_id,
6+
MIN(test_date) AS first_positive_date
7+
FROM covid_tests
8+
WHERE result = 'Positive'
9+
GROUP BY patient_id
10+
),
11+
first_negative_after_positive AS (
12+
SELECT
13+
t.patient_id,
14+
MIN(t.test_date) AS first_negative_date
15+
FROM
16+
covid_tests t
17+
JOIN first_positive p
18+
ON t.patient_id = p.patient_id AND t.test_date > p.first_positive_date
19+
WHERE t.result = 'Negative'
20+
GROUP BY t.patient_id
21+
)
22+
SELECT
23+
p.patient_id,
24+
p.patient_name,
25+
p.age,
26+
DATEDIFF(n.first_negative_date, f.first_positive_date) AS recovery_time
27+
FROM
28+
first_positive f
29+
JOIN first_negative_after_positive n ON f.patient_id = n.patient_id
30+
JOIN patients p ON p.patient_id = f.patient_id
31+
ORDER BY recovery_time ASC, patient_name ASC;

0 commit comments

Comments
 (0)