Я спробував це з різними способами, і найкращий результат, який я знайшов, був цей простий запит:
select a.id+1 gapIni
,(select x.id-1 from arrc_vouchers x where x.id>a.id+1 limit 1) gapEnd
from arrc_vouchers a
left join arrc_vouchers b on b.id=a.id+1
where b.id is null
order by 1
;
... один лівий приєднання, щоб перевірити, чи існує наступний ідентифікатор , лише якщо наступний, якщо його не знайдено, тоді підзапит знайде наступний ідентифікатор, який існує, щоб знайти кінець пробілу. Я зробив це, тому що запит з рівним (=) кращою продуктивністю, ніж більший, ніж оператор (>).
Використовуючи sqlfiddle, він не показує настільки різну продуктивність інших запитів, але в реальній базі даних цей запит приводить до результату в 3 рази швидше, ніж у інших.
Схема:
CREATE TABLE arrc_vouchers (id int primary key)
;
INSERT INTO `arrc_vouchers` (`id`) VALUES (1),(4),(5),(7),(8),(9),(10),(11),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29)
;
Дотримуйтесь нижче всіх запитів, які я зробив для порівняння продуктивності:
select a.id+1 gapIni
,(select x.id-1 from arrc_vouchers x where x.id>a.id+1 limit 1) gapEnd
from arrc_vouchers a
left join arrc_vouchers b on b.id=a.id+1
where b.id is null
order by 1
;
select *, (gapEnd-gapIni) qt
from (
select id+1 gapIni
,(select x.id from arrc_vouchers x where x.id>a.id limit 1) gapEnd
from arrc_vouchers a
order by id
) a where gapEnd <> gapIni
;
select id+1 gapIni
,(select x.id from arrc_vouchers x where x.id>a.id limit 1) gapEnd
#,coalesce((select id from arrc_vouchers x where x.id=a.id+1),(select x.id from arrc_vouchers x where x.id>a.id limit 1)) gapEnd
from arrc_vouchers a
where id+1 <> (select x.id from arrc_vouchers x where x.id>a.id limit 1)
order by id
;
select id+1 gapIni
,coalesce((select id from arrc_vouchers x where x.id=a.id+1),(select x.id from arrc_vouchers x where x.id>a.id limit 1)) gapEnd
from arrc_vouchers a
order by id
;
select id+1 gapIni
,coalesce((select id from arrc_vouchers x where x.id=a.id+1),concat('*** GAT *** ',(select x.id from arrc_vouchers x where x.id>a.id limit 1))) gapEnd
from arrc_vouchers a
order by id
;
Можливо, це комусь корисно і корисно.
Ви можете переглянути та протестувати мій запит за допомогою цієї sqlfiddle :
http://sqlfiddle.com/#!9/6bdca7/1