J'ai deux tables comme celle-ci:
select * from room where room.id not in ( select room2.id from room as room2 inner join reservation r on room2.id = r.room_id where r.check_in > '2020-04-19' and r.check_out < '2020-04-25');
et
Reservation ----------------- id room_id check_in check_out
Je vise à obtenir toutes les chambres qui n'ont pas de réservation, lors d'un période de check_in et check_out spécifique.
Jusqu'à présent, j'ai réussi à créer la requête comme ceci:
Room ----------------- id
Mais je crois qu'il doit y avoir un plus optimal moyen de le faire, en utilisant la jointure gauche.
Comment puis-je créer une requête équivalente, en utilisant uniquement des jointures?
3 Réponses :
Je suggérerais que n'existe pas
:
select r.* from room r where not exists (select 1 from reservation res where r.id = res.room_id and res.check_in > '2020-04-19' and res.check_out < '2020-04-25' );
Notez qu'il n'y a pas besoin d'une jointure
dans la sous-requête (ni dans votre version, mais je déconseille fortement pas
avec les sous-requêtes en raison du traitement des valeurs null
).
En termes de performances, cela devrait être mieux que ou comparable à la jointure gauche
dans la plupart des bases de données. Il peut profiter d'un index sur les réservations (room_id, check_in, check_out)
.
Votre approche pas dans
n'a pas besoin d'une jointure
et aurait pu être exprimée de cette façon. N'utilisez cette option que si vous êtes certain de ne pas avoir de valeurs nulles pour les colonnes pertinentes de la table de réservation.
select t1.* from room t1 inner join (select distinct room_id from reservation where check_in <= '2020-04-19' and check_out >= '2020-04-25') t2 on t1.id=t2.room_id
Si vous insistez pour utiliser une join
select * from room where id not in (select room_id from reservation where check_in > '2020-04-19' and check_out < '2020-04-25');
Je pense que, étant donné le titre «Simplifier la requête de sélectionner dans sélectionner pour utiliser la jointure», l'OP s'attend à résoudre ce problème, en utilisant uniquement des jointures.
Les problèmes XY ne sont pas rares sur Stackoverflow. Je peux me tromper, mais je pense qu'OP a voulu simplifier sa requête et a peut-être pensé que les jointures étaient la voie à suivre. J'ai ajouté une approche utilisant des jointures au cas où vous ne l'auriez pas remarqué.
Vous pouvez le faire avec un LEFT JOIN
où vous filtrez toutes les lignes correspondantes:
select rm.* from room rm left join reservation rs on rs.room_id = rm.room_id and rs.check_in > '2020-04-19' and rs.check_out < '2020-04-25' where rs.room_id is null
Comme vous pouvez le voir, toutes les conditions doivent être placées dans le Clause ON
.