2016-03-11 2 views
0

Мне нужно объединить две таблицы на основе совпадающих данных времени, и я не знаю, как это сделать в SQL. У меня есть таблица событий и времени, таких, как это:Как связать таблицу событий с таблицей интервалов?

Event_Table 
+----------------+-------+ 
|  Event  | Time | 
+----------------+-------+ 
| Fire Alarm  | 10:00 | 
| Smoke Alarm | 13:00 | 
| Security Alarm | 16:00 | 
+----------------+-------+ 

У меня также есть таблица интервалов времени, например, это:

Interval_Table 
+--------+-------------+-----------+ 
| Warden | Shift_Start | Shift_End | 
+--------+-------------+-----------+ 
| Jack | 09:00  | 10:30  | 
| John | 14:00  | 20:00  | 
+--------+-------------+-----------+ 

мне нужно сделать таблицу событий, которая включает в себя который находился в дежурстве в тот момент:

Output_Table 
+----------------+-------+----------------+ 
|  Event  | Time | Warden_On_Duty | 
+----------------+-------+----------------+ 
| Fire Alarm  | 10:00 | Jack   | 
| Smoke Alarm | 13:00 | [null]   | 
| Security Alarm | 16:00 | John   | 
+----------------+-------+----------------+ 

Некоторые сдвиги начальника могут перекрываться, но это следует игнорировать; максимальное имя одного смотрителя должно отображаться для каждого события. Таблицы очень большие (~ 500 000 строк). Любые идеи о том, как это можно достичь с помощью SQL?

+0

Вы не можете просто игнорировать дублирование, вы должны указать, какой вы хотите. –

ответ

0

Вот один из способов сделать это. Обратите внимание, как я разместил расходные данные ddl и образцы данных? Вы должны сделать это в будущем. Это облегчает помощь. Проблема в этом была решена. Сам запрос был тривиальным усилием.

if OBJECT_ID('tempdb..#Event') is not null 
    drop table #Event 

create table #Event 
(
    EventName varchar(20) 
    , EventTime time 
) 

insert #Event 
select 'Fire Alarm', '10:00' union all 
select 'Smoke Alarm', '13:00' union all 
select 'Security Alarm', '16:00' 

if OBJECT_ID('tempdb..#Shifts') is not null 
    drop table #Shifts 

create table #Shifts 
(
    Warden varchar(10) 
    , StartTime time 
    , EndTime time 
) 

insert #Shifts 
select 'Jack', '09:00', '10:30' union all 
select 'John', '14:00', '20:00' union all 
select 'overlap', '15:00', '22:00'; 

with SortedResults as 
(
    select * 
     , ROW_NUMBER() over (partition by e.EventName order by s.StartTime) as RowNum 
    from #Event e 
    join #Shifts s on s.StartTime <= e.EventTime and s.EndTime >= e.EventTime 
) 

select * 
from SortedResults 
where RowNum = 1 
0

Попробуйте это:

select 
    Event, 
    Time, 
    (select top 1 Warden from Interval_Table where Time between Shift_Start and Shift_End) as Warden_On_Duty 
from Event_Table 
Смежные вопросы