Ajuda em query SQL

Firebird

07/05/2014

Boa tarde pessoal. Estou desenvolvendo um sistema de hotel e estou fazendo a parte de hospedagens/reservas. Tenho uma tabela para quartos, uma para hospedagem e outra para reservas.

[img]http://arquivo.devmedia.com.br/forum/imagem/369526-20140507-145203.png[/img]
[img]http://arquivo.devmedia.com.br/forum/imagem/369526-20140507-145228.png[/img]
[img]http://arquivo.devmedia.com.br/forum/imagem/369526-20140507-145238.png[/img]

Estou realizando o projeto no Delphi e preciso realizar uma filtragem para que na hora de cadastrar uma nova hospedagem ou reserva me retorne apenas os quartos que estejam disponíveis para as datas escolhidas na hora do cadastro. Tinha pensado em fazer algo como isso, mas não deu certo e estou meio perdido:

select * from quartos as q left join reservas as r on q.numeroquartos=r.quartos_numeroquartos left join hospedagem as h on q.numeroquartos=h.quartos_numeroquartos where ((r.dataentradareservas not between '14.04.2014' and '30.04.2014' and r.datasaidareservas not between '14.04.2015' and '30.04.2015') or (r.quartos_numeroquartos is null)) and (h.quartos_numeroquartos is null)

Esse “14/04/2014” seria a data de entrada e esse “30/04/2014” seria a data de saída, escolhidos pelo cliente para a hospedagem, por exemplo.
Acho que disse todas as informações, mas se faltou algo relevante me peçam que eu informo.
Se alguém puder me ajudar em como eu posso fazer minha query agradeço desde já.
Alex Welter

Alex Welter

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

07/05/2014

se eu entendi bem o problema, creio que esta seja a solução:
select q.* 
from quartos q
left join reservas r on
 r.quartos_numeroquartos=q.numeroquartos and
 (('14.04.2014' between r.dataentradareservas and r.datasaidareservas) or ('30.04.2014' between r.dataentradareservas and r.datasaidareservas))
left join hospedagem h on
 h.quartos_numeroquartos=q.numeroquartos and
 ((h.datasaidahospedagem is null) or
  ('14.04.2014' between h.dataentradahospedagem and h.datasaidahospedagem) or
  ('30.04.2015' between h.dataentradahospedagem and h.datasaidahospedagem))
where
  r.quartos_numeroquartos is null and
  h.quartos_numeroquartos is null
GOSTEI 0
Alex Welter

Alex Welter

07/05/2014

Seu código está muito bom, porém testei na base de dados e encontrei um pequeno problema. Quando a dataentrada está antes das datas pesquisada e a datasaida está entre elas (ou quando a dataentrada está entre as datas e a datasaida está depois), ele não seleciona o quarto perfeitamente, mas quando a data de entrada e a de saída estão ambas entre as datas pesquisadas, o quarto aparece como se estivesse disponível (tanto faz se for dataentradahospedagem, dataentradareservas, datasaidahospedagem ou datasaidareservas, o erro acontece em todas).

Por exemplo
Datas escolhidas: 01.03.2014 e 25.04.2014

Quartos indisponíveis:
dataentradahospedagem 27.02 e datasaidahospedagem 05.04
dataentradareservas 20.04 e datasaidareservas 05.05

Quartos disponíveis:
dataentradahospedagem 23.03 e datasaidahospedagem 28.03
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

07/05/2014

publique alguns dados para que seja possível fazer a simulação.

nos testes que eu fiz deu tudo certo, porém fiz com apenas 3 registros.

GOSTEI 0
Emerson Nascimento

Emerson Nascimento

07/05/2014

nova tentativa (tudo na base da lógica, pois não tenho dados para testar):

select q.* 
from quartos q
left join reservas r on
 r.quartos_numeroquartos=q.numeroquartos and
 (('14.04.2014' between r.dataentradareservas and r.datasaidareservas) or
  ('30.04.2014' between r.dataentradareservas and r.datasaidareservas) or
  (r.dataentradareservas between '14.04.2014' and '30.04.2014') or
  (r.datasaidareservas   between '14.04.2014' and '30.04.2014'))
left join hospedagem h on
 h.quartos_numeroquartos=q.numeroquartos and
 ((h.datasaidahospedagem is null) or
  ('14.04.2014' between h.dataentradahospedagem and h.datasaidahospedagem) or
  ('30.04.2015' between h.dataentradahospedagem and h.datasaidahospedagem) or
  (h.dataentradahospedagem between '14.04.2014' and '30.04.2014') or
  (h.datasaidahospedagem   between '14.04.2014' and '30.04.2014'))
where
  r.quartos_numeroquartos is null and
  h.quartos_numeroquartos is null
GOSTEI 0
Alex Welter

Alex Welter

07/05/2014

Nossa cara, obrigado! Agora a query funcionou perfeitamente. Muito obrigado mesmo!
GOSTEI 0
POSTAR