Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

mas2

Verificar registros que não estão entre um período de datas

Recommended Posts

Olá pessoal!

 

Preciso de ajuda de como fazer uma consulta na seguinte situação:

 

- um período de datas (data inicial e data final) vindas de um formulário;

- um período de datas (data inicial e data final) vindas do banco;

 

Como fazer uma consulta que verifique quais registros não estão no cruzamento entre esses períodos, ou seja, uma "interseção ao contrário" (acho que como uma operação de diferença entre conjuntos, mas não sei como fazer com períodos de datas).

 

Estou utilizando o PHP e o MySQL.

 

Muito Obrigada.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Motta.

 

Muito obrigada pela resposta. Consegui resolver parte do problema.

 

Com esta consulta, consigo retornar as acomodações que já foram reservadas, mas estão livres no período (no caso, de 2014-07-03 a 2014-07-05). As acomodações que nunca foram reservadas não aparecem no resultado da consulta.

Acho que preciso mudar a estrutura do banco...

CREATE TABLE IF NOT EXISTS acomodacao (
id INT NOT NULL AUTO_INCREMENT,
nome VARCHAR(45) NOT NULL,
numero INT NOT NULL,
vldiaria FLOAT NOT NULL,
acomodacao_tipo INT NOT NULL,
FOREIGN KEY (acomodacao_tipo) REFERENCES acomodacao_tipo (id),  
PRIMARY KEY (id)
)  ENGINE=MYISAM DEFAULT CHARSET=latin1;


CREATE TABLE IF NOT EXISTS reserva (
id INT NOT NULL AUTO_INCREMENT,
id_cliente INT NOT NULL,
id_acomodacao INT NOT NULL,
dtinicial date DEFAULT NULL,
dtfinal date DEFAULT NULL,
FOREIGN KEY (id_cliente) REFERENCES cliente (id),  
FOREIGN KEY (id_acomodacao) REFERENCES acomodacao (id),  
PRIMARY KEY (id)
)  ENGINE=MYISAM DEFAULT CHARSET=latin1;

A consulta:

SELECT a.id, a.nome, a.acomodacao_tipo, a.vldiaria
FROM acomodacao a, reserva re
WHERE re.id_acomodacao = a.id
AND NOT EXISTS (

SELECT * 
FROM reserva r
WHERE (
r.dtinicial
BETWEEN  '2014-07-03'
AND  '2014-07-05'
)
OR (
r.dtfinal
BETWEEN  '2014-07-03'
AND  '2014-07-05'
)
OR (
 '2014-07-03'
BETWEEN r.dtinicial
AND r.dtfinal
)
OR (
 '2014-07-05'
BETWEEN r.dtinicial
AND r.dtfinal
)

)

Se vc puder me ajudar, eu agradeço muito. Sou iniciante em SQL e preciso terminar esse trabalho...

Compartilhar este post


Link para o post
Compartilhar em outros sites
Consegui resolver esse problema... mas agora quando seleciono um intervalo de datas que está reservado para uma acomodação, as outras que estão "livres" não aparecem no resultado da consulta.




SELECT a.id, a.nome, a.acomodacao_tipo, a.vldiaria
FROM acomodacao a LEFT JOIN reserva re ON re.id_acomodacao = a.id
WHERE NOT EXISTS
(
SELECT *
FROM reserva r
WHERE (
r.dtinicial
BETWEEN '$dataInicial'
AND '$dataFinal'
)
OR (
r.dtfinal
BETWEEN '$dataInicial'
AND '$dataFinal'
)
OR (
'$dataInicial'
BETWEEN r.dtinicial
AND r.dtfinal
)
OR (
'$dataFinal'
BETWEEN r.dtinicial
AND r.dtfinal
)
)
GROUP BY a.id

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não é necessário usar o not exists.

 

A parte do [inline]r.dtinicial BETWEEN '$dataInicial' AND '$dataFinal'[/inline] está correta, mas não precisa ser dentro de uma subquery, agora, para saber quais acomodações estão livres, use [inline]re.id IS NULL[/inline], desta forma é retornado o que já está reservado no período e as acomodações livres.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá, lokaodomau. Obrigada pela resposta. Fiz a alteração q vc falou, mas desta forma só aparecem as acomodações que estão reservadas no período. Como faço para ver as acomodações livres?

Desculpe pela pergunta, mas sou mt iniciante em SQL...

SELECT a.id, a.nome, a.acomodacao_tipo, a.vldiaria  
FROM acomodacao a LEFT JOIN reserva r  ON r.id_acomodacao = a.id
WHERE 
 (
r.dtinicial
BETWEEN  '$dataInicial'
AND  '$dataFinal'
)
OR (
r.dtfinal
BETWEEN  '$dataInicial'
AND  '$dataFinal'
)
OR (
 '$dataInicial'
BETWEEN r.dtinicial
AND r.dtfinal
)
OR (
 '$dataFinal'
BETWEEN r.dtinicial
AND r.dtfinal
)
AND r.id IS NULL
GROUP BY a.id

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tenta remover esta parte para ver se resolve:

 

OR (
r.dtfinal
BETWEEN '$dataInicial'
AND '$dataFinal'
)
OR (
'$dataInicial'
BETWEEN r.dtinicial
AND r.dtfinal
)
OR (
'$dataFinal'
BETWEEN r.dtinicial
AND r.dtfinal
)

Mantenha somente a condição que eu disse estar certa (não precisa nem estar dentro dos parenteses) e a dica que dei...

 

Entenda minha lógica:

Para cada acomodação pode haver n reservas, mas para cada reserva, existe apenas 1 acomodação, esta acomodação está identificada em cada reserva, se eu pesquisar um período dentro das reservas, encontrarei um número x de acomodações ocupadas, portanto, todas as demais estarão vagas, é aí que entra o "r.id IS NULL", que é para exibir todas as acomodações que não possuem reserva no período, sendo assim, ou a acomodação está ocupada no período, ou está vaga.

 

OBS: Da maneira que expliquei anteriormente não tinha ficado claro, mas nessa consulta você irá encontrar as reservas no período OU as acomodações vagas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.