PAYATHON 2026

如何用 Python 按 treatment_id 整理 MySQL 查询结果?

数据小许

结论

再执行一次 SELECT,然后在 Python 中按 treatment_id 分组即可。可以用 collections.defaultdict 收集每项治疗的记录,再整理成 [treatment_id, treatment, [(due_time, ts_id), ...]] 这样的结构,不必为每项治疗单独查询。

用 defaultdict 分组

下面按题目示例中的五列数据处理:treatment_id、patient_id、treatment、due_time 和排期 ID。题目中的 SQL 实际返回六列,还包含 status。如果游标结果里有这一列,需要根据实际列的位置调整取值。

from collections import defaultdict

groups = defaultdict(list)

for treatment_id, patient_id, treatment, due_time, schedule_id in data:
    groups[treatment_id].append((treatment, due_time, schedule_id))

result = [
    [treatment_id, rows[0][0], [(due_time, schedule_id) for _, due_time, schedule_id in rows]]
    for treatment_id, rows in groups.items()
]

result 的结构符合预期:

[
    [13, 'co-amox 2.3ml IV', [(16, 1), (14, 3), (12, 4), (13, 9), (6, 10), (4, 11), (22, 12), (18, 13)]],
    [14, 'metacam 4.8kg dose PO SID', [(22, 14), (1, 15), (7, 16), (6, 17)]]
]

如果需要保留 status,可以把它加进排期元组,例如 (due_time, status, schedule_id),也可以存成字典,之后按字段名访问。

直接按查询列处理

题目中的查询列顺序是 treatment_id, patient_id, treatment, due_time, status, ts_id,循环可以这样写:

from collections import defaultdict

groups = defaultdict(list)

for treatment_id, patient_id, treatment, due_time, status, ts_id in rows:
    groups[treatment_id].append((treatment, due_time, status, ts_id))

result = [
    [treatment_id, items[0][0], [(due_time, status, ts_id) for _, due_time, status, ts_id in items]]
    for treatment_id, items in groups.items()
]

这里假设每个 treatment_id 对应唯一的治疗名称。如果不符合这一点,可以把治疗名称也加入分组键,或检查查询结果中的名称为何不一致。

填充 24 小时时间线

如果 GUI 每小时只需显示是否有排期,可以先把该治疗的小时值转成集合,再依次检查 0 到 23:

hours = {due_time for due_time, _ in schedules}

cells = ['x' if hour in hours else '' for hour in range(24)]

如果同一小时可能有多条排期,集合只会保留“该小时有排期”这一信息。需要区分具体排期时,可以保留该小时对应的排期 ID 或状态。

排序与查询次数

如果结果需要按时间顺序显示,可以在分组后排序:

for items in groups.values():
    items.sort(key=lambda item: item[1])  # 五列示例中,索引 1 是 due_time

数据库返回的结果没有明确的排序保证。需要稳定顺序时,应在 SQL 中加上合适的 ORDER BY,例如 ORDER BY t.treatment_id, ts.due_time。一次查询取回当前日期和患者的数据后,通常可以直接在内存中分组;按 treatment_id 逐个查询会增加数据库往返次数。

备注:内容仅供参考。