Выберите строку из таблицы t1, где ученик остается вместе, согласно столбцу даты, времени и продолжительности. - PullRequest
0 голосов
/ 30 марта 2019

У меня есть таблица t1 с четырьмя столбцами, и я хочу получить строку, где учащиеся останутся два или более раз за раз

идея: добавьте значение продолжительности каждого учащегося в дату-время, затем сравните с датой-временем до столбца

Student    date       time    Duration
   a       12-09-19 11:12:30    30
   b       12-09-19 11:13:30    60
   c       12-09-19 11:14:00    60
   d       12-09-19 11:18:30    40

результаты, которые я хочу

Student    date       time   Duration
   b       12-09-19 11:13:30    60
   c       12-09-19 11:14:00    60

вручную добавьте длительность, затем найдите b студента 11:13:30 + 60 = 11:14:30, который больше, чем студент c временем даты, так что b и c остаются вместе 30 секунд

Ответы [ 2 ]

0 голосов
/ 30 марта 2019

Согласен, разделение даты и времени не очень хорошая идея для оракула. Простое решение состоит в том, чтобы найти всех студентов, которые приходят, когда другой уже есть, или, наоборот, другой уже там, когда студент прибывает.

Настройка

alter session set nls_Date_format = 'dd.mm.yyyy hh24:Mi:ss';

create table test (
Student  varchar2(31),
sdate    date,   
Duration number);

insert into test values  ('a','12-09-19 11:12:30',30);
insert into test values  ('b','12-09-19 11:13:30',60);
insert into test values  ('c','12-09-19 11:14:00',60);
insert into test values  ('d','12-09-19 11:18:30',40);

SQL

select * from test t 
where exists  (select 'x' from test where t.sdate between sdate and sdate + (duration / (24*60*60)) and t.student != student)
  or  exists  (select 'x' from test where sdate between t.sdate and t.sdate + (t.duration / (24*60*60)) and t.student != student);  
0 голосов
/ 30 марта 2019

Вот один вариант (Oracle; я не говорю на MySQL).

Разделение даты и времени - плохая идея;эти значения должны содержаться в том же столбце DATE типа данных (что я и сделал; если ваша модель действительно использует два столбца, сначала объедините их, а затем примените функцию TO_DATE).

Что это делает?

  • T1 CTE - ваши данные выборки
  • INTER добавляет DURATION количество секунд к каждому значению столбца DATUM (DATE имя столбца будет недопустимым,что касается Oracle, поскольку он зарезервирован для имени типа данных)
  • последний SELECT возвращает студентов, чьи значения INTER.DATIME перекрываются

SQL> alter session set nls_Date_format = 'dd.mm.yyyy hh24:Mi:ss';

Session altered.

SQL> with t1 (student, datum, duration) as
  2    (select 'a', to_date('12.09.2019 11:12:30', 'dd.mm.yyyy hh24:mi:ss'), 30 from dual
  3     union all
  4     select 'b', to_date('12.09.2019 11:13:30', 'dd.mm.yyyy hh24:mi:ss'), 60 from dual
  5     union all
  6     select 'c', to_date('12.09.2019 11:14:00', 'dd.mm.yyyy hh24:mi:ss'), 60 from dual
  7     union all
  8     select 'd', to_date('12.09.2019 11:18:30', 'dd.mm.yyyy hh24:mi:ss'), 40 from dual
  9    ),
 10  inter as
 11    (select student, datum, duration,
 12            datum + (column_value - 1) / (24 * 60 * 60) datime
 13     from t1,
 14          table(cast(multiset(select level from dual
 15                              connect by level <= duration + 1
 16                             ) as sys.odcinumberlist))
 17    )
 18  select distinct student, datum, duration
 19  from inter
 20  where datime in (select datime
 21                   from inter
 22                   group by datime
 23                   having count(*) > 1);

S DATUM                 DURATION
- ------------------- ----------
b 12.09.2019 11:13:30         60
c 12.09.2019 11:14:00         60

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...