É difícil encontrar uma resposta completa para você aqui, pois você está apenas nos mostrando a tabela que contém as reservas - não podemos saber qual a variedade de quartos disponíveis.
O SQL que retorna os room_id's para quartos reservados para pelo menos parte do período selecionado pode ser:
SELECT `room_id` , COUNT(*)
FROM `bookings`
WHERE `dt` BETWEEN "[start date]" AND "[end date]"
GROUP BY `room_id`;
Se você tivesse uma tabela de quartos (em vez de reservas), seria possível retornar uma lista de todos os quartos não reservados durante esse período com:
SELECT `id`
FROM `rooms`
WHERE `id` NOT IN (
SELECT DISTINCT( `room_id` )
FROM `bookings`
WHERE `dt` BETWEEN "[start date]" AND "[end date]"
);
EMENDA
Com base no feedback do OP, as suposições agora são:
- A tabela contém detalhes dos quartos que estão disponíveis por um período que começa na data na coluna
dt
e terminando no dia seguinte (ou seja, quartos de hotel) - A consulta deve retornar todos os quartos disponíveis durante todo o período inserido (portanto, apenas os quartos disponíveis do DIA A ao DIA B serão devolvidos.
Assim, o código alterado é:
SELECT room_id
FROM available_rooms
WHERE dt BETWEEN "[start date]" AND DATE_SUB("[end date]",INTERVAL 1 DAY)
GROUP BY room_id
HAVING COUNT(*)=ABS(DATEDIFF("[start date]","[end date]"));