1

对我来说,这种情况很难解释,但我想获得一份准备好参加解雇会议的用户(实际上是“患者”)列表。

情况

我有一个病人表:

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)

我的查询

我现在正在寻找一个我真的想不出的查询。我的逻辑是:

  1. 选择所有患者;
  2. 最后状态(基于时间戳)来自阶段名称“C”或“D”;
  3. 没有类型为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)

我的问题

在上面的查询中,我有两件事无法管理:

  1. 我的名单中有双重患者。任何处于 D 阶段的患者也会作为处于 C 阶段的患者出现(所以加倍)。我尝试了SELECT DISTINCT但没有成功
  2. 我现在根据名称排除阶段,但我想从状态中按时间戳排序阶段,并且只从那里查看最后状态

广告 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 大师来帮助我吗?

4

1 回答 1

0
SELECT p.id, p.name, max(ph.name) as phase

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 (m.type != 'meeting_planned' OR m.type IS NULL)
    AND p.id not in (
        select p.id
        from 
            patient p
            inner join
            status s on p.id = s.patient_id
            inner join
            phase ph on ph.id = s.phase_id
        where ph.name > 'D'
        ) s
group by p.id, p.name
于 2012-10-09T14:20:17.013 回答