Как записать условия в self join, которые меняются в зависимости от текущей итерации строки - PullRequest
2 голосов
/ 15 мая 2019

Таблица (тест) имеет описание

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| task  | varchar(2)  | NO   |     | NULL    |       |
| time  | int(11)     | NO   |     | NULL    |       |
| type  | char(1)     | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

и содержит данные

+------+------+------+
| task | time | type |
+------+------+------+
| T1   |    1 | S    |
| T2   |    2 | S    |
| T1   |    7 | E    |
| T1   |    8 | S    |
| T1   |   14 | E    |
| T2   |   15 | E    |
| T1   |   16 | S    |
| T2   |   17 | S    |
| T3   |   20 | S    |
| T1   |   21 | E    |
| T3   |   25 | E    |
+------+------+------+

представляет набор данных для задачи, запущенной (S) или завершенной (E) в определенный момент времениБлок.Можно ли присоединить его таким образом, чтобы выводилась таблица с указанием времени начала и окончания задачи.здесь (T2, 17, S) пропускается в конечном выводе, поскольку для него еще нет данных о времени окончания.

Конечный результат: -

+------+------+------+
| task | start| end  |
+------+------+------+
| T1   |    1 | 7    |
| T2   |    2 | 15   |
| T1   |    8 | 14   |
| T1   |   16 | 21   |
| T3   |   20 | 25   |
+------+------+------+

Как видно из конечного результата, все временные рамки для задачи T (T1) являются взаимоисключающими [(1,7), (8, 15), (16,25)].

Невозможно определить правила условий для объединения

select S_table.task, S_table.time as start, E_table.time as end
from (select * from test where type='S') as S_table
left join (select * from test where type='E') as E_table
on
S_table.task = E_table.task
and
E_table.time should be greater than previous E_table.time for same task
and
E_table.time should be least within S_table.time < E_table.time
  • В таблице результатов для первой строки все E_table.время (7,15,14,21,25) больше, чем S_table.time (текущая строка просматривается, т. е. 1), но 7 - это наименьшее значение, поэтому выбрано

  • В таблице результатовдля второй строки все E_table.time больше предыдущего (7), т.е. (15,14,21,25) больше 2, но выбран как минимум один, т.е. 15

1 Ответ

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

Для каждого времени запуска вам нужно получить минимальное время типа 'E', которое больше этого времени запуска:

select t.* from (
  select 
    t.task,
    t.time start,
    (select min(time) from test where type = 'E' and task = t.task and time > t.time) end
  from test t 
  where t.type = 'S' 
) t
where t.end is not null

См. Демоверсию .
Результаты:

| task | start | end |
| ---- | ----- | --- |
| T1   | 1     | 7   |
| T2   | 2     | 15  |
| T1   | 8     | 14  |
| T1   | 16    | 21  |
| T3   | 20    | 25  |

Вы можете получить те же результаты с внутренним самостоятельным соединением, как ваш код:

select S_table.task, S_table.time as start, E_table.time as end
from (select * from test where type='S') as S_table
inner join (select * from test where type='E') as E_table
on
S_table.task = E_table.task
and 
E_table.time = (
  select min(time) from test where type = 'E' and task = S_table.task and time > S_table.time
)
order by S_table.time
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...