I used this answer as a reference.
You can use the following query to find the gaps, which in essence will give you the deleted record "ranges". For example, in the below example, you get 2 rows back in the final result, and the values are 2 and 3, and 6 and 7. So you know that rows with IDs of 2 through 3 have been deleted, and rows with IDs of 6 through 7 have been deleted (for a total of 4 deleted rows).
I believe this meets your requirement of getting the final result in "1 SQL query", and plus, no intermediate or dummy tables are used.
delimiter $$
use test
$$
create table mytable (id int not null auto_increment, name varchar(100), primary key (id));
$$
insert into mytable (name) values('a')$$
insert into mytable (name) values('b')$$
insert into mytable (name) values('c')$$
insert into mytable (name) values('d')$$
insert into mytable (name) values('e')$$
insert into mytable (name) values('f')$$
insert into mytable (name) values('g')$$
insert into mytable (name) values('h')$$
delete from mytable where id = 2$$
delete from mytable where id = 3$$
delete from mytable where id = 6$$
delete from mytable where id = 7$$
SELECT (t1.id + 1) as gap_starts_at
, (SELECT MIN(t3.id) -1
FROM mytable t3
WHERE t3.id > t1.id) as gap_ends_at
FROM mytable t1
WHERE NOT EXISTS (SELECT t2.id FROM mytable t2 WHERE t2.id = t1.id + 1)
HAVING gap_ends_at IS NOT NULL
Output:
gap_starts_at gap_ends_at
2 3
6 7