Как найти разницу между двумя строками в Mysql (версия 5.6) по идентификаторам - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть такие данные

  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

То, что я хочу, - это разница в столбце даты между отправленным и рецензируемым для студента_ид

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

С самостоятельным объединением и агрегацией:

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. Смотрите демо . Результаты:

> 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
0 голосов
/ 20 апреля 2020

Это было бы намного проще (и более эффективно) в MySQL 8.0, где мы использовали бы для этого оконные функции.

В более ранних версиях одним из вариантов является использование коррелированного подзапроса для извлечения дата следующего просмотра для каждого представления:

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) (порядок столбцов в индексе важен здесь).

Демонстрация на 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      |
...