【问题标题】:mysql : check if column id is Consecutive [closed]mysql:检查列ID是否连续[关闭]
【发布时间】:2020-06-24 08:46:34
【问题描述】:

我有一个包含 ID 的表。

+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  6 |
|  9 |
|  7 |
| 10 |

5 号和 8 号不在表中。 我只想从表中选择那些行

【问题讨论】:

    标签: mysql sql phpmyadmin


    【解决方案1】:

    如果你想要缺少ids,一个选项是递归查询来生成号码列表,然后not exists(这需要MySQL 8.0):

    with cte as (
        select min(id) id, max(id) max_id from mytable
        union all 
        select id + 1, max_id from cte where id < max_id
    )
    select c.id
    from cte c
    where not exists (select 1 from mytable t where t.id = c.id)
    

    【讨论】:

    • 我有 MySQL 5.7 。什么是“cte”,你是我的表名吗
    【解决方案2】:

    您可以通过查看上一行来找出差距。如果您的表不是太大:

    select (t.prev_id + 1) as first_missing,
           (t.id - 1) as last_missing,
           (t.id - t.prev_id - 1) as cnt
    from (select t.*,
                 (select max(t2.id) 
                  from t t2
                  where t2.id < t.id
                 ) as prev_id
          from t
         ) t
    where t.prev_id <> t.id - 1;
    

    实际上,在早期版本的 MySQL 中,将其拆分为单独的行是很棘手的,除非您有一个数字或计数表。

    如果你的数据很大,你可以改用变量:

    select (t.prev_id + 1) as first_missing,
           (t.id - 1) as last_missing,
           (t.id - t.prev_id - 1) as cnt
    from (select t.*,
                 (case when (@temp := @prev) = null
                       then null  -- never happens
                       when (@prev := id) = null       
                       then null  -- never happens
                       else @temp
                   end) as prev_id
          from (select t.* from t order by id) t cross join
               (select @prev := -1) params
         ) t
    where t.prev_id <> t.id - 1;
    

    【讨论】:

    • 我试过你的查询。我在两者中都收到错误In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 't.prev_id'; this is incompatible with sql_mode=only_full_group_by。我假设是 count(*) as cnt 导致它。
    • @Scratte 。 . .不需要聚合。我修复了查询。
    【解决方案3】:
    SELECT MIN(id) - 1 id
    FROM ( SELECT id, id - @group_number:=@group_number + 1 group_number
           FROM test, (SELECT @group_number := 0) init_variable
           ORDER BY id ) subquery
    GROUP BY group_number
    HAVING id;
    

    fiddle

    如果有很多连续丢失的号码,只会退回最后一个。

    【讨论】:

      猜你喜欢
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-20
      相关资源
      最近更新 更多