我的表t1包含4列,并且想要获得学生一次要停留两个或更多的行
想法:将每个学生的持续时间值添加到日期时间,然后与上列日期时间进行比较
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秒
答案 0 :(得分:0)
这是一个选择(Oracle;我不会说MySQL)。
分割日期和时间是个坏主意;这些值应包含在同一DATE
数据类型列中(这是我所做的;如果您的模型确实使用了两列,请先将它们连接起来,然后应用TO_DATE
函数)。
这是做什么的?
T1
CTE是您的示例数据INTER
将DURATION
的秒数加到每个DATUM
列值(就Oracle而言,DATE
列名将是无效的,因为保留给数据类型名称)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>
答案 1 :(得分:0)
我同意,在Oracle中分割日期和时间不是一个好主意。一种简单的解决方案是找到一个已经存在的所有学生,或者一个学生抵达时签证/反过来已经存在的另一个学生。
设置
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);