我想知道是否有人可以帮我解决这个问题
我有以下查询:
SELECT * FROM `E935308` WHERE date BETWEEN '2015-09-03' AND '2015-09-03' ORDER BY date, time, id
结果如下:
date time event
2015-09-03 23327 4
2015-09-03 23402 5
2015-09-03 23434 4
2015-09-03 23991 5
2015-09-03 24030 4
2015-09-03 24195 45
2015-09-03 24210 5
2015-09-03 24627 4
2015-09-03 24634 5
2015-09-03 26348 4
2015-09-03 26370 46
2015-09-03 27152 5
2015-09-03 28407 4
2015-09-03 28408 5
2015-09-03 29856 4
2015-09-03 30428 45
2015-09-03 30449 46
2015-09-03 30514 45
2015-09-03 30540 46
2015-09-03 30555 45
2015-09-03 30617 46
2015-09-03 30631 45
有四个事件(4,5,45和46) 假设:4 = START,5 = STOP,45 = IN,46 = OUT
我需要一个算法来向我显示第一个事件编号4的时间,然后是在45之后的第4个和第46个之后的前45个时间以及事件46之后的前5个时间。
这是一个有效的例子:
2015-09-03 23327 24195 26370 27152
2015-09-03 28407 30428 30449 -
2015-09-03 28407 30514 30540 -
破折号表示事件5不存在。
我不知道这是否可行,仍然值得一试。
感谢您的帮助。
编辑:
为了清楚一点,如何消除括号内的数字?
[4]
5
4
5
4
[45]
5
4
5
4
[46]
[5]
4
5
答案 0 :(得分:1)
编辑:第一个解决方案是错误的。
可能有更优雅的解决方案,但这里只有4个事件,您可以通过5个变量进行单次扫描。
当你有连接时,这个解决方案就会消失,所以如果是这样的话,你必须在内部子选择中封装所有连接和顺序,这样变量 - 魔法就会发生在一个清晰的单个有序数据流上。所有查询必须在同一SQL连接中发送,否则您将失去变量。
如果你忽略外部选择而只是使用内部选择,你会看到没有真正的魔法发生,只是简单的if-then在MySQL中。
其他信息,你甚至可以修改它来测量In和Out之间的时间。
fiddle显示其工作原理,fiddle获取结果。在您的示例中,您忘记了tou 128407, 30555, 30617, -1
set @found4=0;
set @found5=0;
set @found45=0;
set @found46=0;
set @current45=0;
select first4, current45, first46, max(first5)
from (
select `date`, `time`, event, @found4:=if(event=4 and @found4=0, time+@found5 := 0, @found4) as first4,
@found45:=if(event=45 and @found4>0 and @found45=0, time + @found46 := 0, @found45) as first45,
@found46:=if(event=46 and @found4>0 and @found45>0 and @found46 = 0, time + (@current45:=@found45) - @found45 + @found45 :=0, @found46) as first46,
@current45 as current45,
@found5:=if(event=5 and @found4>0 and @found46 > 0 and @found5 = 0, time + @found4:=0 + @found45 := 0 + @found46 := 0, @found5 ) as first5
from t0 order by `date`, `time`
) as innersel where first4>0 and first46 > 0 group by first4, current45, first46;
这给出了
first4 current45 first46 max(first5)
23327 24195 26370 27152
28407 30428 30449 0
28407 30514 30540 0
28407 30555 30617 0
结果。
我希望您在设置和重置变量时看到“状态机”。我必须添加和减去@found45
才能设置@current45
,但不能打扰@found46
。
答案 1 :(得分:0)
这是一个基于flaschenpost答案的php解决方案我知道它并不是一个伟大的,但它接近我需要的。仍然只有一个问题。
$req="SELECT * FROM t0 WHERE date BETWEEN '2015-09-03' AND '2015-09-03' ORDER BY date, time, id";
$q = $conn->prepare($req);
$q->execute();
$event1 = 0;
$event2 = 0;
$event3 = 0;
$event4 = 0;
while($r=$q->fetch()){
if($r['event'] == 4 and $event1 == 0) {
echo $r['time'] . ' - ' . $r['event'] . '<br>';
$event1 = 1;
$event2 = 0;
$event3 = 0;
$event4 = 0;
}
if($r['event'] == 45 and $event1 == 1) {
echo $r['time'] . ' - ' . $r['event'] . '<br>';
$event1 = 1;
$event2 = 1;
$event3 = 0;
$event4 = 0;
}
if($r['event'] == 46 and $event1 == 1) {
echo $r['time'] . ' - ' . $r['event'] . '<br>';
$event1 = 1;
$event2 = 1;
$event3 = 1;
$event4 = 0;
}
if($r['event'] == 5 and $event1 == 1 and $event2 == 1 and $event3 == 1) {
echo $r['time'] . ' - ' . $r['event'] . '<br><br>';
$event1 = 0;
$event2 = 0;
$event3 = 0;
$event4 = 0;
}
}
结果是:
23327 - 4 -> Start Event 1
24195 - 45
26370 - 46
27152 - 5 -> End Event 1
28407 - 4 -> Start Event 2
30428 - 45
30449 - 46 -> This must be considered the End of Event 2
30514 - 45 -> This must be considered the Start of Event 3
30540 - 46 -> This must be considered the End of Event 3
30555 - 45
30617 - 46
30631 - 45
30687 - 46
30723 - 45
34059 - 46
34073 - 45
34479 - 46
34499 - 5
34660 - 4
34665 - 45
35007 - 46
35009 - 45
36505 - 45
36505 - 46
36525 - 5
47085 - 4
正如您所看到的,可能存在我们没有事件4和5的情况,因此我们必须仅显示事件45和46。
感谢任何帮助。