使用查询在mysql中查找最长的免费ID范围?

时间:2012-04-02 10:02:51

标签: mysql

这当然可以使用简单的脚本并读取数据库来完成。 我很想知道使用一些MySQL查询是否可行。

表架构:

+--------+-------------------------------+
| doc_id | doc_title                     |
+--------+-------------------------------+
| 40692  | hello                         |
| 13873  | isaac                         |
| 37739  | einstei                       |
| 36042  | cricket                       |
| 96249  | astronaut                     |
| 81931  | discovery                     |
| 28447  | scooby                        |
| 99632  | popeye                        |
+--------+-------------------------------+

这里doc_id是1到99999之间的随机数,分布很稀疏。我想知道我的mysql表中最长的(或所有最长的)未使用的数字范围。 即如果71000到83000是这个范围最长的范围,则没有记录在这两个值之间有doc_id。

4 个答案:

答案 0 :(得分:2)

create table documents ( id int, name varchar(255) );

insert into documents (id, name ) values

( 40692,'hello'),
( 13873,'isaac'),
( 37739,'einstei'),
( 36042,'cricket'),
( 96249,'astronaut'),
( 81931,'discovery'),
( 28447,'scooby'),
( 99632,'popeye')

select
    d1.id,
    min( d2.id ),
    min( d2.id ) - d1.id as 'gap'
from
    documents d1
    join documents d2 on d2.id > d1.id
group by
    d1.id
order by
    3 desc;

答案 1 :(得分:2)

尝试此查询 -

SELECT start_doc_id, doc_id end_doc_id, delta FROM (
  SELECT
    doc_id,
    @d start_doc_id,
    IF(@d IS NULL, 0, doc_id - @d) delta,
    @d:=doc_id
  FROM
    doc, (SELECT @d:= NULL) t
    ORDER BY doc_id
  ) doc
ORDER BY delta DESC

答案 2 :(得分:1)

这样的事情

SELECT t1.doc_id,
       MAX(t1.doc_id-IFNULL(t2.doc_id,0)) AS difference
FROM `table` t1
    LEFT JOIN `table` t2 ON t1.doc_id>t2.doc_id
    LEFT JOIN `table` t3 ON (t1.doc_id>t3.doc_id AND t3.doc_id>t2.doc_id)
WHERE t3.doc_id IS NULL
GROUP BY t1.doc
ORDER BY difference DESC

答案 3 :(得分:0)

如果您的文档表变大(数十万或数百万条记录),我会寻找Wolfgang的不同解决方案,因为使用“on d2.id> d1.id”的连接将创建巨大的临时表并花费大量时间。

如果创建临时表,你可以快速完成:

create table tdoc (id int, nextid int);
insert into tdoc (id) (select id from documents);
update tdoc join documents as d1 
  on d1.id = tdoc.id
  set nextid = 
    (select id from documents 
    where id > tdoc.id order by id limit 1);
select id, max(nextid-id) from tdoc;

没有自我加入,没有沉重的嘎吱嘎吱声;如有必要,此解决方案可扩展到大型文档表