MySQL从表中获取缺少的ID

Rea*_*cen 31 mysql

我在MySQL中有这个表,例如:

ID | Name
1  | Bob
4  | Adam
6  | Someguy
Run Code Online (Sandbox Code Playgroud)

如果您注意到,则没有ID号(2,3和5).

如何编写查询以便MySQL只回答缺少的ID,在这种情况下:"2,3,5"?

hag*_*oft 28

SELECT a.id+1 AS start, MIN(b.id) - 1 AS end
    FROM testtable AS a, testtable AS b
    WHERE a.id < b.id
    GROUP BY a.id
    HAVING start < MIN(b.id)
Run Code Online (Sandbox Code Playgroud)

希望这个链接也有助于 http://www.codediesel.com/mysql/sequence-gaps-in-mysql/

  • 工作正常:),但大数据非常慢:( (3认同)

Ivá*_*rez 24

一个更有效的查询:

SELECT (t1.id + 1) as gap_starts_at, 
       (SELECT MIN(t3.id) -1 FROM my_table t3 WHERE t3.id > t1.id) as gap_ends_at
FROM my_table t1
WHERE NOT EXISTS (SELECT t2.id FROM my_table t2 WHERE t2.id = t1.id + 1)
HAVING gap_ends_at IS NOT NULL
Run Code Online (Sandbox Code Playgroud)


Tri*_*ley 9

如果您不想返回多个 ID 范围,而是想要检索每个缺失的 ID 本身(每个 ID 位于其自己的行上),则可以执行以下操作:

SELECT id+1 FROM table WHERE id NOT IN (SELECT id-1 FROM table) ORDER BY 1
Run Code Online (Sandbox Code Playgroud)

查询非常高效。但是,它还包括末尾的一个额外行,该行等于最高 ID 号加 1。通过检查返回的行数 ( mysqli_num_rows ),然后使用,可以在服务器脚本中忽略最后一行。for如果行数大于 1,则循环(查询将始终返回至少一行)。

编辑: 我最近发现,在丢失的号码是连续的(即彼此相邻)的情况下,我的原始解决方案没有返回所有丢失的 ID 号码。然而,该查询对于快速确定是否有数字丢失仍然很有用,并且与 hagensoft 的查询(最佳答案)结合使用时可以节省时间。换句话说,可以首先运行此查询来测试丢失的 ID。如果发现任何东西,那么之后可以立即运行 hagensoft 的查询,以帮助识别丢失的确切 ID(不会节省时间,但速度也不会慢很多)。如果没有找到任何内容,则可能会节省大量时间,因为不需要运行 hagensoft 的查询。

  • 非常简单,非常聪明,非常快。事实上,如果表太大,则接受的版本在合理的时间内是不可行的(大意味着 200,000 条记录)。 (2认同)