MySql Расписание запроса - PullRequest
2 голосов
/ 18 января 2020

У меня есть таблица базы данных, которая вводится из необработанных данных. В нем есть список поездов, который отформатирован следующим образом:

RI   TrainNo   TripNo   Location   ArrTime   DepTime
TS:  171       1        HMS                  17280
TE:  171       8        UPM        45360    
TS:  171       9        UPM                  53640
TE:  171       16       HMS        87120    

TS - это точка, с которой начинается поезд, а TE - точка, с которой заканчивается поезд.

Я хочу установить sh если поезд движется в определенное время, выполните следующий запрос:

SELECT DISTINCT tt.TrainNo
              , s1.StartTime
              , s1.StartTrip
              , s1.StartLocation
              , s2.StowTime
              , s2.StowTrip
              , s2.StowLocation 
           FROM `tt.data` tt 
           JOIN 
              ( SELECT TrainNo
                     , DepTime as StartTime
                     , TripNo as StartTrip
                     , Location as StartLocation 
                  FROM `tt.data` 
                 WHERE RI = 'TS:' 
              ) s1 
           JOIN 
              ( SELECT TrainNo
                     , ArrTime StowTime
                     , TripNo StowTrip
                     , Location StowLocation 
                  FROM `tt.data` 
                 WHERE RI = 'TE:' 
              ) s2 
             ON s1.TrainNo = tt.TrainNo 
            AND s1.TrainNo = s2.TrainNo 
            AND s1.StartTime < s2.StowTime
            AND 45350 > s1.StartTime 
            AND 45350 < s2.StowTime 
            AND tt.TrainNo = 171

Вывод:

TrainNo StartTime StartTrip StartLocation StowTime StowTrip StowLocation
171     17280     1         HMS           45360    8        UPM
171     17280     1         HMS           87120    16       HMS

Первая строка верна, и поезд ход между трипсами 1 и 8. Однако второй ряд неверен, если время было больше 45360, то это сообщило бы мне, что поезд движется, хотя на самом деле он снова не работает до 53640.

Что бы быть хорошим способом удаления этой строки?

Надеюсь, это имеет смысл.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 18 января 2020

Например:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(TripNo   SERIAL PRIMARY KEY
,RI CHAR(2) NOT NULL
,TrainNo INT NOT NULL 
,Location CHAR(3) NOT NULL
,ArrTime INT NULL
,DepTime INT NULL
);

INSERT INTO my_table VALUES
( 1,'TS',171,'HMS',NULL,17280),
( 8,'TE',171,'UPM',45360,NULL),
( 9,'TS',171,'UPM',NULL,53640),
(16,'TE',171,'HMS',87120,NULL);

SELECT a.*
     , b.*
  FROM 
     ( SELECT x.* 
            , MIN(y.tripno) y_trip 
         FROM my_table x 
         JOIN my_table y 
           ON y.tripno > x.tripno 
          AND y.trainno = x.trainno 
          AND y.ri = 'te' 
        WHERE x.ri = 'ts' 
        GROUP 
           BY x.tripno
     ) a
  JOIN my_table b
    ON b.tripno = a.y_trip
 WHERE 45350 BETWEEN a.deptime AND b.arrtime;

+--------+----+---------+----------+---------+---------+--------+--------+----+---------+----------+---------+---------+
| TripNo | RI | TrainNo | Location | ArrTime | DepTime | y_trip | TripNo | RI | TrainNo | Location | ArrTime | DepTime |
+--------+----+---------+----------+---------+---------+--------+--------+----+---------+----------+---------+---------+
|      1 | TS |     171 | HMS      |    NULL |   17280 |      8 |      8 | TE |     171 | UPM      |   45360 |    NULL |
+--------+----+---------+----------+---------+---------+--------+--------+----+---------+----------+---------+---------+
0 голосов
/ 18 января 2020

Я думаю оконные функции делают то, что вы хотите:

select d.*
from (select d.*,
             lead(arrtime) over (partition by trainno order by tripno) as next_arrtime
      from tt.data d
     ) d
where ri = 'TS:' and
      45350 > deptime and
      45350 < next_arrtime
0 голосов
/ 18 января 2020

Ключом к решению этой проблемы является правильное самостоятельное присоединение к началу и концу каждой поездки. Один из способов сделать это для данного поезда - найти ближайший конечный пункт того же поезда. Это можно сделать с помощью коррелированного подзапроса, например:

select 
    t1.trainno,
    t1.deptime  starttime,
    t1.tripno     starttrip,
    t1.location startlocation,
    t2.arrtime  stowtime,
    t2.tripno     stowtrip,
    t2.location stowlocation
from mytable t1
inner join mytable t2 
    on  t2.trainno = t1.trainno
    and t2.ri = 'TE:'
    and t2.arrtime = (select min(t3.arrtime) from mytable t3 where t3.arrtime > t1.deptime)
where 
    t1.ri = 'TS:'
    and t1.trainno = 171
    and t1.deptime < 45350
    and t2.arrtime > 45350

Демонстрация на DB Fiddle :

trainno | starttime | starttrip | startlocation | stowtime | stowtrip | stowlocation
------: | --------: | --------: | :------------ | -------: | -------: | :-----------
    171 |     17280 |         1 | HMS           |    45360 |        8 | UPM         
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...