Группируйте запрос, когда учитель, предмет одинаковы, и между классами нет временного интервала - PullRequest
0 голосов
/ 08 мая 2019

Ниже я приведу структуру некоторых таблиц, чтобы проиллюстрировать, что я пытаюсь сделать.

Учитывая, что время занятий каждого учащегося составляет 30 минут, я хотел бы выбрать расписание учащегося, но мне нужно сгруппировать записи, в которых расписания занятий последовательные (по 30 минут, без перерыва) иучитель и предмет одинаковы

Я использую SQL Server 2017.

ученик

id      name
1       Oliver
2       Jack
3       Harry

учитель

id      name
1       Amelia
2       Olivia

предмет

id       subject
1        Mathematics
2        Science

расписание

id  startdatetime            idstudent   idteacher    idsubject
1   2019-05-30 08:00         1            1           2
2   2019-05-30 08:40         1            1           2
3   2019-05-30 09:10         1            1           2
3   2019-05-30 09:40         1            2           2
4   2019-05-30 10:10         1            2           1

При выборе по idstudent, я хотел бы отобразить результат в виде группы следующим образом:

Qty    startdatetime       teacher    subject
1      2019-05-30 08:00    Amelia     Science
2      2019-05-30 08:40    Amelia     Science   grouped in a single row(qty 2) because the class time has 30 minutes without interval, teacher and subject are the same.
1      2019-05-30 09:40    Olivia     Science
1      2019-05-30 10:10    Olivia     Mathematics

Заранее спасибо!

1 Ответ

0 голосов
/ 08 мая 2019

Это тип проблемы групп и островов. Я фокусируюсь только на таблице schedule. Вы можете присоединиться к другим таблицам по своему усмотрению.

Чтобы определить, где начинается группа, используйте lag(). Затем совокупная сумма определяет группу, и агрегат получает то, что вы хотите:

select count(*) as qty,
       idstudent, idteacher, idsubject
from (select s.*,
             sum(case when prev_sdt > dateadd(minute, -30, startdatetime)
                      then 1 else 0
                 end) over (partition by s.idstudent, s.idteacher, s.idsubject order by s.startdatetime) as grp
      from (select s.*,
                   lag(s.startdatetime) over (partition by s.idstudent, s.idteacher, s.idsubject order by s.startdatetime) as prev_sdt
            from schedule s
           ) s
     ) s
group by by idstudent, idteacher, idsubject, grp
order by min(startdatetime);
...