Mysql 根据记录的条目查找用户列表

Mysql 根据记录的条目查找用户列表,mysql,distinct,Mysql,Distinct,对我来说,这个场景很难解释,但我想得到一个用户列表,这些用户实际上是准备好参加解雇会议的患者 形势 我有一张病床: PATIENT id (int) name (varchar) 患者遵循一个特殊的过程,我定义了阶段: PHASE id (int) name (varchar) 我记录了患者的所有阶段: STATUS id (int) phase_id (int) patient_id (int) timestamp (datetime) “准备开会”一词意味

对我来说,这个场景很难解释,但我想得到一个用户列表,这些用户实际上是准备好参加解雇会议的患者

形势

我有一张病床:

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; 没有计划会议类型的消息。 广告2:患者可以处于两个阶段之一。如果患者处于a、B、E或F阶段,则无法计划会面。当患者处于C阶段时,护士可能已经决定安排会议,但如果没有,则会在D阶段进行。D阶段始终在C阶段之后,即A>B>C>D>E>F

广告3:可能还有其他消息,但这种类型的消息永远不会出现。类型+患者id上有一个唯一的约束。如果会议已计划且已发生,则有两条消息类型1=会议计划,类型2=会议完成。如果没有计划会议,则不会出现“计划的会议”类型,但可能已经设置了其他消息

我试过什么

我现在提出了这个问题:

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期的患者出现,所以会加倍。我尝试了一个选择不同,但没有成功 我现在根据阶段的名称排除它们,但我想从状态中对时间戳上的阶段进行排序,并且只从那里查看最后一个状态 广告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
我现在不能在这里使用GROUPBY,因为我必须使用COUNT或类似的分组函数


这里有SQL专家帮助我吗?

谢谢,你在我问题的第一部分帮助了我。那确实奏效了!有了更多的测试数据,我的名字和博士名字似乎更合适E'不会取消选择已经处于E阶段的用户,因为他们仍然有状态日志,表明他们也处于C和D阶段。我现在选择了太多的患者,但我想我可以通过子查询来处理这些问题……谢谢,我自己也提出了这个子查询。接受了答案,这是一个快速的反应!
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