我有一张表 Works ,在其中有 开始日期 和 结束日期 列>是日期时间类型和 qtty tinyint。为了涵盖这些作品,我得到了另一个名为 Turns 的表,该表具有 start_turn 和 end_turn 两种日期时间类型也一样。
需要为大于或等于 qtty 的人数(分配了转弯数)的人遮盖作品,但不一定需要将转弯数从 works.start_date 到 works.end_date 。
我需要知道的是作品是否被适当地覆盖,我的意思是,是否总是为至少来自 的 qtty 人覆盖作品?开始日期 到 结束日期 。
例如:案例1
工作=> 开始日期 = 2018-07-01 10:00 | 结束日期 = 2018-07-01 22:00 | qtty = 2
转弯=>
人物A: 开始转弯 = 2018-07-01 10:00 | end_turn = 2018-07-01 22:00
人物B: 开始转弯 = 2018-07-01 10:00 | end_turn = 2018-07-01 16:00
人物C: 开始转弯 = 2018-07-01 16:00 | end_turn = 2018-07-01 22:00
案例2
工作=> 开始日期 = 2018-07-01 10:00 | 结束日期 = 2018-07-01 22:00 | qtty = 2
转弯=>
人物A: 开始转弯 = 2018-07-01 10:00 | end_turn = 2018-07-01 22:00
人物B: 开始转弯 = 2018-07-01 16:00 | end_turn = 2018-07-01 22:00
人物C: 开始转弯 = 2018-07-01 16:00 | end_turn = 2018-07-01 22:00
看到第一种情况,我们可以解决该问题,只需提取工作时间乘以 qtty ,然后将该值与每个回合的分钟总和进行比较,然后答案是“是”,则正确地覆盖了工作。但是将这种方法应用于第二种情况,答案也是“是”,但这是不正确的,因为从 开始日期 到 < em> end_date 。
我该怎么做?任何帮助将不胜感激。
编辑
这是正确的SQL提琴:http://sqlfiddle.com/#!9/c53d1b
答案 0 :(得分:1)
不是答案;评论太久了:
Case 1 : Qtty = 2
10 11 12 13 14 15 16 17 18 19 20 21 22
A |------------------------------------|
B |------------------|
C |-----------------|
Case 2 : Qtty = 2
10 11 12 13 14 15 16 17 18 19 20 21 22
A |------------------------------------|
B |-----------------|
C |-----------------|
案例2似乎满足了“那些作品不一定需要从works.start_date到works.end_date”的要求
答案 1 :(得分:0)
不是一个完整的答案,只是一个大概的想法。
要解决此问题,您必须开箱即用,以稍微不同的方式提出问题。
让我们举两个例子。对于情况1,您有3个时间点-10、16、22。这意味着2个间隔-从10到16和从16到22。对于第一个间隔,您有2个匝数完全包含间隔-A和B。第二个间隔有2个回合,完全包含间隔-A和C。
对于情况2,您具有相同的时间点和相同的子间隔。但是,这一次间隔10-16,您只有1个转弯,完全包含了该间隔-转弯A。因此,在这种情况下,转弯未完全覆盖所需的转弯< / strong>。
我仍然不确定如何在单个SQL查询中实现这一点-也许您将不得不从存储过程开始,以过程的方式通过循环来执行操作,然后在您更好地理解后对其进行优化这个想法。
这里有一些SQL可以为您提供初始近似值,您将根据自己的口味(http://sqlfiddle.com/#!9/72e841/3)进行调整:
select * from
(select p_start,p_end,qty -
(select count(*) from turns
where start_turn <= p_start
and end_turn >= p_end
) as non_covered
from
(select pt, @start:=@end AS p_start, @end:=pt AS p_end
from
(select start_date as pt from work where id=1
union
select end_date as pt from work where id=1
union
select start_turn from turns, work
where work.id=1
and start_turn between start_date and end_date
union
select end_turn from turns, work
where work.id=1
and start_turn between start_date and end_date
) as tmp
order by pt
) as period
join work on work.id = 1
where p_start <> p_end
) as cover
where non_covered > 0