Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Dúvida bem básica:
Tenho duas tabelas: produtos e reservas. Preciso listar os produtos que NÃO constam na reserva por um determinada período.
Faço com um innerJoin e um foreach de produtos com if($produto!=$reserva_id) ou dois foreach sendo um com reservas e depois nos produtos != reservas naquele período?
Não tou conseguindo fazer a listagem corretamente.
-----PRODUTO--------------RESERVAS------------
produto_id reserva_id
produto_nome produto_id
produto_status data_reserva
------------------------------------------------
"SELECT imoveis.imv_id, imoveis_reservas.imv_id FROM imoveis INNER JOIN imoveis_reservas ON imoveis.imv_id =imoveis_reservas.imv_id"
Gabriel, agradeço muito pela resposta e peço desculpa pela demora.
Agora lhe faço uma pergunta: se quiser comparar o mesmo período em dois campos da tabela, como faço?
o período digitado precisa ser pesquisado na data de entrada e data de saida.
Tentei desta maneira mais não funciona:
"SELECT * from imoveis WHERE NOT EXISTS (SELECT * from imoveis_calendario WHERE imoveis_calendario.imv_id = imoveis.imv_id and start BETWEEN '2018-05-22' AND '2018-05-28' OR end BETWEEN '2018-05-22' AND '2018-05-28')"
Se faço apenas o select interno retorna o resultado correto:
SELECT * from imoveis_calendario WHERE start BETWEEN '2018-05-22' AND '2018-05-28' OR end BETWEEN '2018-05-22' AND '2018-05-28'
Se puder me ajudar, agradeço muito.O que exatamente você quer comparar nesses períodos. Pois, normalmente, em um período é comparado apenas a data atual.
Explique como quer comparar, para entedermos o que deve ser feito.
Oi Gabriel.
Então, na verdade eu estava errada, preciso apenas um between no período de saida, o de entrada não importa.
Eu tenho um form de busca que o hóspede procura imóveis que estejam disponível.
Ele digita um período - start e end e faço a pesquisa listando apenas os imóveis disponíveis.
AI no caso eu procuro apenas na DATA DE SAIDA o intervalo que o hóspede selecionar.
"SELECT * from imoveis WHERE NOT EXISTS (SELECT * from imoveis_calendario WHERE imoveis_calendario.imv_id = imoveis.imv_id and end BETWEEN '2018-05-22' AND '2018-05-28')"
Agradeço.Acredito que tenha resolvido então?
só uma dica, não retorne asterísco (*) no select do exists. Adicione um valor simples, como foi no exemplo (SELECT 'x'). Ai não precisará retornar dados reais, tornando a consulta mais rápida.
Olá, tudo bem ? espero que sim.
Abaixo segue parte do Código que uso o INNER JOIN.
<?php
//Faço conexão com o MySql
$sql_pegaAtivos = 'SELECT pro.codProdClie, pro.produtoDescr, pro.apres_unid, pro.clienteId,
cota.cotaId, cota.cotaItensId, cota.cotaNumImport, cota.cotaNumero, cota.cotaQtde, cota.cotaComenta,
cota.codProdClie
FROM cotacaoItens cota
INNER JOIN produto pro ON pro.codProdClie = cota.codProdClie
WHERE pro.clienteId = :clienteId
AND cota.cotaNumero = :cotaNumero
ORDER BY cota.cotaItensId ASC';
try{
$query_pegaAtivos = $conecta->prepare($sql_pegaAtivos);
$query_pegaAtivos->bindValue(':clienteId',$clienteId,PDO::PARAM_STR);
$query_pegaAtivos->bindValue(':cotaNumero',$cotaNumero,PDO::PARAM_STR);
$query_pegaAtivos->execute();
$resultado_pegaAtivos = $query_pegaAtivos->fetchAll(PDO::FETCH_ASSOC);
$count_pegaAtivos = $query_pegaAtivos->rowCount(PDO::FETCH_ASSOC);
}catch(PDOexception $error_pegaAtivos){
echo 'Erro ao pegar ativos';
}
//Trago os dados usando o Foreach
foreach($resultado_pegaAtivos as $resAtivos){
$cotaId = $resAtivos['cotaId'];
$clienteId = $resAtivos['clienteId'];
$cotaItensId = $resAtivos['cotaItensId'];
$cotaNumero = $resAtivos['cotaNumero'];
$cotaNumImport = $resAtivos['cotaNumImport'];
$codProdClie = $resAtivos['codProdClie'];
$cotaQtde = $resAtivos['cotaQtde'];
$cotaComenta = $resAtivos['cotaComenta'];
$descrProd = $resAtivos['produtoDescr'];
$apresProd = $resAtivos['apres_unid'];
}
?>
Espero ter ajudado.Eu posso usar o between desta maneira?
SELECT imv_id,data_start,data_end FROM imoveis_calendario WHERE '2018-06-16' BETWEEN data_start AND data_end OR '2018-09-15' BETWEEN data_start and data_end
São duas datas **Data de entrada** e **Data de saida** eu preciso verificar os imoveis que estarão ocupados em um período.
Similar os site: [https://www.booking.com/](https://www.booking.com/)Acho que lógica é mais para esta aqui:
data_start BETWEEN '2018-06-16' AND '2018-09-15'
OR data_end BETWEEN '2018-06-16' AND '2018-09-15'
OR (data_start < '2018-06-16' AND data_end > '2018-09-15')
Basicamente a lógica é a seguinte:
-
Data de início está no período da pesquisa;
-
Data de término está no período da pesquisa;
-
As datas de reserva abrangem um período maior que o solicitado.
É a terceira lógica que você está deixando de lado. Por exemplo, eu estou pesquisando no período de 10/05/2018 até 20/05/2018. Se alguém fez uma reserva em um perído maior (09/05/2018 até 21/05/2018), sua consulta não iria considerá-lo.
Nossa, por isso que não listava alguns que deveria listar! ...quebrando a cabeça aqui!
Então na verdade usando o NOT IN por exemplo, fica assim:
"SELECT imv_id AS Id FROM imoveis WHERE imv_id NOT IN (SELECT imv_id FROM
imoveis_calendario WHERE imv_id =imoveis.imv_id AND start BETWEEN
'2018-05-12' AND '2018-05-22' OR end BETWEEN '2018-05-12' AND '2018-05-22')"
Agradeço.
Deu certinho aqui, brigadão Gabriel!
A referência em "aplicações temporais de RDBMS/SQL": https://www.amazon.com/Developing-Time-Oriented-Database-Applications-Management/dp/1558604367
Você também pode usar um "banco de dados temporal/de séries temporais" se quiser.
Ambas as tratativas não irão funcionar, este não é o propósito do INNER JOIN.
Se você quiser resultados que estão em uma tabela, mas, não estão em outra, utilize a cláusula NOT IN ou NOT EXISTS. O último sendo um pouco mais rápido que o primeiro.
IN
FROM table1 WHERE FROM table1 WHERE NOT EXISTS (SELECT 'x' FROM table2 WHERE table2.table1id = table1.id)