Если вы можете жить с отсутствием пропуска до первого идентификатора в базе данных (и запроса с использованием 'временной таблицы', 'файловой сортировки' и 'буфера соединения' ) :
SELECT
a.id + 1 AS `From`,
MIN(b.id - 1) AS `To`
FROM
foo as a, foo as b
WHERE
a.id < b.id
GROUP BY
a.id
HAVING
a.id < min(b.id) -1
автономный пример:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// usually I create temporary tables for example scripts, but
// self-joins don't work on temp tables in mysql, bare me....
$pdo->exec('CREATE TABLE soFoo ( id int, primary key(id))');
$pdo->exec('INSERT INTO soFoo (id) VALUES (5),(6),(7),(8),(10),(15),(21)');
foreach( $pdo->query('
SELECT
a.id + 1 AS `From`,
MIN(b.id - 1) AS `To`
FROM
foo as a, foo as b
WHERE
a.id < b.id
GROUP BY
a.id
HAVING
a.id < min(b.id) -1', PDO::FETCH_ASSOC) as $row
) {
echo $row['From'], ' - ', $row['To'], "\n";
}
печать
9 - 9
11 - 14
16 - 20