使用GROUP BY从MySql数据库中获取第二高的值

使用GROUP BY从MySql数据库中获取第二高的值,mysql,sql,group-by,Mysql,Sql,Group By,我有一个表tbl_患者,我想取每个患者的最后2次就诊,以比较患者的病情是改善还是恶化 tbl_patient id | patient_ID | visit_ID | patient_result 1 | 1 | 1 | 5 2 | 2 | 1 | 6 3 | 2 | 3 | 7 4 | 1 | 2 | 3 5 | 2

我有一个表tbl_患者,我想取每个患者的最后2次就诊,以比较患者的病情是改善还是恶化

tbl_patient

id | patient_ID | visit_ID | patient_result
1  |     1      |   1      |     5
2  |     2      |   1      |     6
3  |     2      |   3      |     7
4  |     1      |   2      |     3
5  |     2      |   3      |     2
6  |     1      |   3      |     9
我尝试了下面的查询,以获取每位患者的最后一次就诊

SELECT MAX(id), patient_result FROM `tbl_patient` GROUP BY `patient_ID`
现在,我想通过查询获取每个患者的第二次最后就诊,但它给了我错误 1242-子查询返回超过1行

如果我错了

为什么不简单地使用

GROUP BY `patient_ID` DESC LIMIT 2
。。。剩下的在下一步做什么

SELECT id, patient_result FROM `tbl_patient` t1
JOIN (SELECT MAX(id) as max, patient_ID FROM `tbl_patient` GROUP BY `patient_ID`) t2 
      ON t1.patient_ID = t2.patient_ID
WHERE id <max GROUP BY t1.`patient_ID`
id11是最后一次就诊的ID,id2是第二次至最后一次就诊的ID。

试试这个

SELECT id, patient_result FROM tbl_patient AS tp WHERE id < ((SELECT MAX(id) FROM tbl_patient AS tp_max WHERE tp_max.patient_ID = tp.patient_ID)  - 1) GROUP BY patient_ID

您的第一个查询不会得到最后的访问,因为它给出的结果是5和6,而不是2和9。 您可以尝试以下查询:

SELECT patient_ID,visit_ID,patient_result
FROM tbl_patient
where id in (
    select max(id) 
    from tbl_patient
    GROUP BY patient_ID)
union
SELECT patient_ID,visit_ID,patient_result
FROM tbl_patient
where id in (
    select max(id) 
    from tbl_patient
    where id not in (
        select max(id) 
        from tbl_patient
        GROUP BY patient_ID)
    GROUP BY patient_ID)
order by 1,2

有几种方法可以获取在单个SQL语句中返回的指定resultset

不幸的是,这些方法中的大多数产生了相当笨拙的声明

在处理大型集合时,外观更优雅的语句往往表现不佳或难以忍受。而那些性能更好的语句看起来更不优雅

三种最常见的方法利用了:

相关子查询 不等式几乎是笛卡尔乘积 两次传递数据 这是一种使用MySQL用户变量对数据进行两次传递的方法,它基本上模拟了分析等级的过度分配。。。其他DBMS中可用的功能:

请注意,这是使用了一个依赖子查询,这基本上意味着对于从t返回的每一行,MySQL都有效地对数据库运行另一个查询。因此,就大型设备的运行时间而言,这将是非常昂贵的

作为另一种方法,如果每个患者的id值相对较少,则您可能可以通过不平等连接:


请注意,这将为每个患者创建一个近似笛卡尔积。对于每个患者有限数量的id值,这不会太糟糕。但是如果一个患者有数百个id值,中间结果可能是巨大的,顺序为on**2。

这将结果限制为总共两行,不是每个患者2个。@jcjr我更新了我的问题,在子查询中提到了错误alsoIn,您正在按患者id分组。由于有许多患者id,它返回多行MAXid-1是否是有效的mysql语句?@PRPGFerret是的,但它对此没有用。MAXid-1可能是另一个患者。它将第一个患者的最后一次就诊和第二个患者的第一次就诊按子句添加到外部查询。非常感谢,您的查询非常有效,但我对p1.,id1,id2等等。你能详细解释一下吗?因为我不太擅长SQL。这些只是用来标识表和结果列的别名。当连接两个具有相同列名的表或子查询时,需要指定别名来引用它们。当你有一个像maxp1.id这样的计算结果时,你必须使用一个别名,这样你就可以参考结果。它只会获取每个患者的第一次就诊
SELECT id, patient_result FROM tbl_patient AS tp WHERE id < ((SELECT MAX(id) FROM tbl_patient AS tp_max WHERE tp_max.patient_ID = tp.patient_ID)  - 1) GROUP BY patient_ID
SELECT patient_ID,visit_ID,patient_result
FROM tbl_patient
where id in (
    select max(id) 
    from tbl_patient
    GROUP BY patient_ID)
union
SELECT patient_ID,visit_ID,patient_result
FROM tbl_patient
where id in (
    select max(id) 
    from tbl_patient
    where id not in (
        select max(id) 
        from tbl_patient
        GROUP BY patient_ID)
    GROUP BY patient_ID)
order by 1,2
SELECT t.id
     , t.patient_id
     , t.visit_id
     , t.patient_result
  FROM (
         SELECT p.id
              , p.patient_id
              , p.visit_id
              , p.patient_result
              , @rn := if(@prev_patient_id = patient_id, @rn + 1, 1) AS rn
              , @prev_patient_id := patient_id AS prev_patient_id
           FROM tbl_patients p
           JOIN (SELECT @rn := 0, @prev_patient_id := NULL) i
          ORDER BY p.patient_id DESC, p.id DESC
       ) t
WHERE t.rn <= 2
SELECT t.id
     , t.patient_id
     , t.visit_id
     , t.patient_result
  FROM tbl_patients t
 WHERE ( SELECT COUNT(1) AS cnt
           FROM tbl_patients p
          WHERE p.patient_id = t.patient_id
            AND p.id >= t.id
       ) <= 2
 ORDER BY t.patient_id ASC, t.id ASC
SELECT t.id
     , t.patient_id
     , t.visit_id
     , t.patient_result
  FROM tbl_patients t
  LEFT
  JOIN tbl_patients p
    ON p.patient_id = t.patient_id 
   AND t.id < p.id
 GROUP
    BY t.id
     , t.patient_id
     , t.visit_id
     , t.patient_result
HAVING COUNT(1) <= 2