对我来说,这种情况很难解释,但我想获得一份准备好参加解雇会议的用户(实际上是“患者”)列表。
情况
我有一个病人表:
PATIENT
id (int)
name (varchar)
患者遵循一个特殊的过程,我在其中定义了阶段:
PHASE
id (int)
name (varchar)
我记录了患者的所有阶段:
STATUS
id (int)
phase_id (int)
patient_id (int)
timestamp (datetime)
术语“准备会议”是指会议已计划好。此类计划会议记录在消息表中。计划会议的消息具有类型“meeting_planned”,例如,当会议结束时,会有一条新消息“meeting_done”。
MESSAGE
id (int)
patient_id (int)
type (enum)
value (varchar)
timestamp (datetime)
我的查询
我现在正在寻找一个我真的想不出的查询。我的逻辑是:
- 选择所有患者;
- 最后状态(基于时间戳)来自阶段名称“C”或“D”;
- 没有类型为meeting_planned的消息。
广告 2:患者可能处于两个阶段之一。当患者处于 A、B、E 或 F 阶段时,无法计划会议。当患者处于 C 阶段时,护士可能已经决定安排会议,但如果没有发生,它将在 D 阶段进行(D 始终跟随 C,即 A>B>C>D>E>F)。
广告 3:可能还有其他消息,但绝不是这种类型。在 type+patient_id 上有一个独特的约束。如果会议已计划并已发生,则有两条消息(类型 1 = meeting_planned,类型 2 = meeting_done)。如果尚未计划会议,则不会出现类型 meeting_planned,但可能已经设置了其他消息。
我尝试了什么
我现在想出了这个查询:
SELECT p.id, p.name, ph.name
FROM patient p
LEFT JOIN status s ON p.id=s.patient_id
LEFT JOIN phase ph ON ph.id=s.phase_id
LEFT JOIN message m ON p.id=m.patient_id
WHERE (ph.name='C' OR ph.name='D')
AND (ph.name != 'E')
AND (m.type != 'meeting_planned' OR m.type IS NULL)
我的问题
在上面的查询中,我有两件事无法管理:
- 我的名单中有双重患者。任何处于 D 阶段的患者也会作为处于 C 阶段的患者出现(所以加倍)。我尝试了
SELECT DISTINCT
但没有成功 - 我现在根据名称排除阶段,但我想从状态中按时间戳排序阶段,并且只从那里查看最后状态
广告 1:它现在看起来像这样:
ID NAME PHASE
1 John C
2 Jane C
3 Tom C
4 Pete C
5 Anna C
1 John D
2 Jane D
3 Tom D
显然我想要这个:
ID NAME PHASE
4 Pete C
5 Anna C
1 John D
2 Jane D
3 Tom D
我现在不能GROUP BY
在这里使用,因为我必须使用COUNT
类似或类似的分组函数。
这里有任何 SQL 大师来帮助我吗?