【问题标题】:MySQL: Sort events by start time, immediatly followed by finish eventMySQL:按开始时间对事件进行排序,紧随其后的是完成事件
【发布时间】:2017-11-28 07:48:34
【问题描述】:

我的数据库中有这样的事件数据:

 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 行),我现在更新了示例。

有什么想法吗?

【问题讨论】:

    标签: mysql performance sorting events alternate


    【解决方案1】:

    如果结束时间总是在开始时间之后,这应该可以工作

    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)
    

    【讨论】:

    • 对了,我忘了说对象号是可以复用的(不过有一个单独的id我没有加简单,可能是我抽象太多了)
    • @TomSmartBishop 请修改您的问题以包含此附加信息。我会在 5 分钟内删除这个答案。
    【解决方案2】:

    您可以简单地依赖事件类型的顺序。因为 e 在 s 之前,所以降序排序。

    select time, obj, type
       from someTable
       order by obj, type desc
    

    【讨论】:

    • 不幸的是,我没有重复对象 ID,它应该按开始事件时间排序
    猜你喜欢
    • 2018-04-30
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    • 2018-12-17
    • 2015-05-21
    • 1970-01-01
    相关资源
    最近更新 更多