因此,对于未通过只绘制我会加理解这个问题的家伙与所提供的数据业务方案的问题画在这里。
这是一种只有在你已经处理过的情况下才能理解的问题。
dt2 dt3|dt4 dt5 dt8 dt9
T1 : [-----]|[-----] [---------]
dt1 dt6 dt7 dt10
T2 : [--------------------------] [--------------------------]
R1s R1e R2s R2e R3s R3e R4s R4e
R : [----] [-------] [--------] [-------]
标签是指:
dt1 - Date 1
dt2 - Date 2
....
dt10 - Date 10
-------
R1s - Result date start 1
R1e - Result date end 1
R2s - Result date start 2
R2e - Result date end 2
...
他们的日期和时间的时期。请注意,日期3和4之间的|
只是表明在此之间没有间隔。
我的解决方案
对于这类问题,你要做的第一件事就是要知道你所有的时间开始和两端为一体的,所以我用它创建了一个VIEW
我将不止一次使用它的最终选择(如果你愿意,你不需要创建视图只是使用查询作为子查询)
create or replace view vw_times as
select dtstart as dtperiod from t1 UNION
select dtend from t1 UNION
select dtstart from t2 UNION
select dtend from t2;
这种观点会给我所有的时间(开始和结束)只在一个领域dtperiod
我还需要另一种观点认为对UNION ALL来自T1
starts
和ends
和T2
所以
create or replace view vw_times2 as
select dtstart, dtend from t1 UNION
select dtstart, dtend from t2;
所以最终的查询将是:
SELECT t.dtstart, t.dtend
FROM (
SELECT t1.dtperiod as dtstart,
(SELECT min(dtperiod) second
FROM vw_times x where x.dtperiod > t1.dtperiod) as dtend
FROM vw_times t1
LEFT JOIN (SELECT (dtperiod - interval 1 second) dtperiod
FROM vw_times) t2
ON (t1.dtperiod = t2.dtperiod)
WHERE t2.dtperiod is null
) t LEFT JOIN vw_times2 t2 ON ( t.dtstart = t2.dtstart
AND t.dtend = t2.dtend)
WHERE t2.dtstart IS NULL
AND DAY(t.dtstart) = DAY(t.dtend)
ORDER BY t.dtstart;
请记住,我正在使用我在此查询中创建的视图,以便它更具可读性。
在这个查询上值得一提。由于您只希望每天的缺失时间段结束,因此我添加了此筛选器AND DAY(t.dtstart) = DAY(t.dtend)
,因此查询不会让您在几天之间遗漏时间段。在你的样本集中,因为查询期间的调整,它将是2015-05-14 23:00:00 2015-05-16 12:00:00
和2015-05-16 14:00:00 NULL
最后一个。
这里是SQLFiddle工作的解决方案:使用MySQL http://sqlfiddle.com/#!9/6a8a9/1
注意,我创建它(sqlfiddle)(因为它与SQLSERVER不稳定)。由于它只使用普通的sql,它将在SQLServer上同样工作(唯一的不同是日提取,这里的答案我添加了sqlserver版本)。
图纸不会帮助你的事业。发布实际数据 –
指定您的RDBMS(SQL * flavor *),因为实现中的日期/时间函数不同。 –
@vkp其实它和日期有关。不需要更多信息。 –