Mysql 用于运行长度或连续相同值编码的SQL查询

Mysql 用于运行长度或连续相同值编码的SQL查询,mysql,sql,postgresql,sqlite,gaps-and-islands,Mysql,Sql,Postgresql,Sqlite,Gaps And Islands,我的目标是获取一组按id排序的数据,并返回一个结果集,该结果集指示val列相同的连续行数。例如,根据这些数据: | id | val | | 1 | 33 | | 2 | 33 | | 3 | 44 | | 4 | 28 | | 5 | 44 | | 6 | 44 | 我希望看到这样的结果: | id | val | run_length | | 1 | 33 | 2 | | 3 | 44 | 1 | | 4 | 28 |

我的目标是获取一组按
id
排序的数据,并返回一个结果集,该结果集指示
val
列相同的连续行数。例如,根据这些数据:

| id | val |
|  1 |  33 |
|  2 |  33 |
|  3 |  44 |
|  4 |  28 |
|  5 |  44 |
|  6 |  44 |
我希望看到这样的结果:

| id | val | run_length |
| 1  | 33  | 2          |
| 3  | 44  | 1          |
| 4  | 28  | 1          |
| 5  | 44  | 2          |
resultset中的id列是可选的。事实上,如果这让它变得非常困难,那么只需将该列从结果中删除即可。我有点喜欢它,因为它将结果集“固定”到表中的特定位置

我主要对免费数据库引擎的结果感兴趣。我对解决方案的偏好顺序是:

  • SQLite
  • 博士后
  • MySQL
  • 神谕
  • SQL Server
  • 赛贝斯
  • 我将在您的列表中选择#2,因为在SQLite中用一个查询执行此操作非常痛苦。以下是标准SQL:

    select min(id), val, count(*) as runlength
    from (select t.*,
                 (row_number() over (order by id) -
                  row_number() over (partition by val order by id
                 ) as grp
          from data t
         ) t
    group by grp, val;
    

    这使用两个行号计算的差异来识别相同值的差异。它应该在数据库2、4、5和6的最新版本中工作。

    我一直在SQLITE的RLE空间中徘徊,并浏览了这篇文章。我相信这个代码适用于#1。第一个答案是正确的,这在SQLite中作为单个查询有点痛苦

    create table example (id integer primary key autoincrement, val integer);
    
    insert into example (val) values (33);
    insert into example (val) values (33);
    insert into example (val) values (44);
    insert into example (val) values (28);
    insert into example (val) values (44);
    insert into example (val) values (44);
    
    
    select ren.low_id, e2.val, (ren.high_id - ren.low_id)+1
    from example e2
    inner join (
    select min(hb.low_id) as low_id, hb.high_id as high_id
    from 
    (
        with nexample(low_id, high_id, val) 
        as 
        (
        select e.id, e.id, e.val from example e
        union all
        select ne.low_id, eu.id, ne.val 
        from nexample ne
        inner join example eu on eu.id = ne.high_id+1 AND eu.val=ne.val
        )
        select ne.low_id, max(ne.high_id) as high_id from nexample ne
        group by ne.low_id
    ) hb
    group by hb.high_id
    ) ren on ren.low_id = e2.id;
    
    输出:

    1|33|2
    3|44|1
    4|28|1
    5|44|2
    
    请注意,此解决方案在非常稀疏的集合上性能不佳。。。我正在寻找一种处理稀疏集的替代方法


    例如,在一组10000行上,val集为[0,1],但所有值均为0。此代码在我的硬件上运行大约需要2分钟30秒。不太好。

    未来的一个注意事项-从3.25.0(2018-09-15)开始,这在SQLite中确实有效。查阅