如何通过 ids 查找 Mysql(5.6 版)中两行之间的差异

How to find the difference between two rows in Mysql (version 5.6) by ids

我有这样的数据

  student_id         phase           date
         34          submitted       05-03-2019
         34          review          15-04-2019
         78          submitted       06-12-2018
         34          submitted       25-04-2019
         78          review          01-01-2019
         34          review          08-05-2019

我想要的是这样的

student_id     GapDays  submission-date   reviewdate
34             41       05-03-2019        15-04-2019
34             13       25-04-2019        08-05-2019
78             26       06-12-2018        01-01-2019

我想要的是每个 student_id

提交和审核之间的日期列差异

在 MySQL 8.0 中,这会更简单(也更有效),我们将为此使用 window 函数。

在早期版本中,一种选择是使用相关子查询来检索每次提交的下一次审核日期:

select 
    t.*,
    datediff(review_date, submission_date) gapdays
from (
    select
        student_id,
        date submission_date
        (
            select min(t1.date)
            from mytable t1 
            where 
                t1.student_id = t.student_id 
                and t1.date > t.date
                and t1.phase = 'review'
        ) review_date
    from mytable t
    where t.phase = 'submitted'
) t
order by student_id, submission_date

为了性能,考虑在 (student_id, phase, date) 上建立索引(索引中列的顺序在这里很重要)。

Demo on DB Fiddle:

| student_id | submission_date | review_date | gapdays |
| ---------- | --------------- | ----------- | ------- |
| 34         | 2019-03-05      | 2019-04-15  | 41      |
| 34         | 2019-04-25      | 2019-05-08  | 13      |
| 78         | 2018-12-06      | 2019-01-01  | 26      |

使用自连接和聚合:

select 
  t1.student_id, 
  datediff(min(t2.date), t1.date) gapdays,
  t1.date submissiondate,
  min(t2.date) reviewdate
from tablename t1 inner join tablename t2
on t1.student_id = t2.student_id and t1.date <= t2.date
and t1.phase = 'submitted' and t2.phase = 'review' 
group by t1.student_id, t1.phase, t1.date

如果您还希望结果中包含尚未审核的提交,您可以将 inner join 更改为 left join
demo.
结果:

> student_id | gapdays | submissiondate | reviewdate
> ---------: | ------: | :------------- | :---------
>         34 |      41 | 2019-03-05     | 2019-04-15
>         34 |      13 | 2019-04-25     | 2019-05-08
>         78 |      26 | 2018-12-06     | 2019-01-01