MySQL: 按开始时间排序事件,紧接着是结束事件
MySQL: Sort events by start time, immediatly followed by finish event
我的数据库中有这样的事件数据:
time | obj | type
-------------------
0012 23 start
0014 24 start
0023 25 start
0034 23 end
0056 26 start
0058 23 start (reusing obj 23)
0060 25 end
0100 24 end
0101 23 end
0107 26 end
...
我想按开始事件时间排序,然后是同一对象的结束事件:
time | obj | type
-------------------
0012 23 start
0034 23 end
0014 24 start
0100 24 end
0023 25 start
0060 25 end
0056 26 start
0107 26 end
0058 23 start
0101 23 end
...
到目前为止,我还没有想出一个 SQL 查询来输出这样的数据。当然,我可以只查询所有开始事件,然后在每一行之后从我的 C API 查询相应的结束事件,但我有多个 10.000 个结束事件,这似乎效率很低。
编辑:抱歉,我第一次问这个问题时忘记提到 obj 编号可以重复使用(并且有一个唯一的 id 行),我现在更新了示例。
有什么想法吗?
如果结束时间总是在开始时间之后,这应该可行
select time,obj,type
from t order by obj,time;
但您也可以在排序中使用 case 语句
select time,obj,type
from t
order by obj,
case when type = 'start' then 1
else 2
end;
如果 obj 被重用,那么棘手的一点是在排序之前将开始类型的 id 分配给结束类型
select t1.time,t1.obj,t1.type, t1.id,
case when t2.id is null then t1.id
else t2.id
end as startid
from t t1
left join t t2 on t2.obj = t1.obj and t2.id = (select max(t.id) from t where t.obj = t1.obj and t.id < t1.id and t1.type = 'end')
order by startid,id
+------+------+-------+----+---------+
| time | obj | type | id | startid |
+------+------+-------+----+---------+
| 12 | 23 | start | 1 | 1 |
| 34 | 23 | end | 4 | 1 |
| 14 | 24 | start | 2 | 2 |
| 100 | 24 | end | 8 | 2 |
| 23 | 25 | start | 3 | 3 |
| 60 | 25 | end | 7 | 3 |
| 56 | 26 | start | 5 | 5 |
| 107 | 26 | end | 12 | 5 |
| 58 | 23 | start | 6 | 6 |
| 101 | 23 | end | 9 | 6 |
| 102 | 23 | start | 10 | 10 |
| 103 | 23 | end | 11 | 10 |
+------+------+-------+----+---------+
12 rows in set (0.00 sec)
您可以简单地依赖于事件类型的排序。因为e在s之前,所以排序desc.
select time, obj, type
from someTable
order by obj, type desc
我的数据库中有这样的事件数据:
time | obj | type
-------------------
0012 23 start
0014 24 start
0023 25 start
0034 23 end
0056 26 start
0058 23 start (reusing obj 23)
0060 25 end
0100 24 end
0101 23 end
0107 26 end
...
我想按开始事件时间排序,然后是同一对象的结束事件:
time | obj | type
-------------------
0012 23 start
0034 23 end
0014 24 start
0100 24 end
0023 25 start
0060 25 end
0056 26 start
0107 26 end
0058 23 start
0101 23 end
...
到目前为止,我还没有想出一个 SQL 查询来输出这样的数据。当然,我可以只查询所有开始事件,然后在每一行之后从我的 C API 查询相应的结束事件,但我有多个 10.000 个结束事件,这似乎效率很低。
编辑:抱歉,我第一次问这个问题时忘记提到 obj 编号可以重复使用(并且有一个唯一的 id 行),我现在更新了示例。
有什么想法吗?
如果结束时间总是在开始时间之后,这应该可行
select time,obj,type
from t order by obj,time;
但您也可以在排序中使用 case 语句
select time,obj,type
from t
order by obj,
case when type = 'start' then 1
else 2
end;
如果 obj 被重用,那么棘手的一点是在排序之前将开始类型的 id 分配给结束类型
select t1.time,t1.obj,t1.type, t1.id,
case when t2.id is null then t1.id
else t2.id
end as startid
from t t1
left join t t2 on t2.obj = t1.obj and t2.id = (select max(t.id) from t where t.obj = t1.obj and t.id < t1.id and t1.type = 'end')
order by startid,id
+------+------+-------+----+---------+
| time | obj | type | id | startid |
+------+------+-------+----+---------+
| 12 | 23 | start | 1 | 1 |
| 34 | 23 | end | 4 | 1 |
| 14 | 24 | start | 2 | 2 |
| 100 | 24 | end | 8 | 2 |
| 23 | 25 | start | 3 | 3 |
| 60 | 25 | end | 7 | 3 |
| 56 | 26 | start | 5 | 5 |
| 107 | 26 | end | 12 | 5 |
| 58 | 23 | start | 6 | 6 |
| 101 | 23 | end | 9 | 6 |
| 102 | 23 | start | 10 | 10 |
| 103 | 23 | end | 11 | 10 |
+------+------+-------+----+---------+
12 rows in set (0.00 sec)
您可以简单地依赖于事件类型的排序。因为e在s之前,所以排序desc.
select time, obj, type
from someTable
order by obj, type desc