1
votes

Simplifier la requête de sélectionner dans sélectionner pour utiliser la jointure

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?


0 commentaires

3 Réponses :


1
votes

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) .


0 commentaires

1
votes

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');


2 commentaires

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é.



2
votes

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 .


0 commentaires