内连接和右连接相同的查询

Nic*_*ier 4 mysql innodb join

我使用MySQL和InnoDB,我有一个表reserver2列:idReservationidChambre 我有一个表reservation和表chambre

现在我希望我的查询返回每个不在我的 dateDebut 和 dateFin 之间的“chambre.id”。

以下是我的实际查询:

SELECT cre.id
FROM   reserver AS rer
       INNER JOIN reservation AS ron
         ON rer.idReservation = ron.id
       RIGHT JOIN chambre AS cre
         ON rer.idChambre = cre.id
WHERE (ron.dateFin < ?
    OR ron.dateDebut > ?
    OR (ron.dateFin = NULL AND ron.dateDebut = NULL))
Run Code Online (Sandbox Code Playgroud)

我的问题是当 chambre 的 id 已经在 Reserver 中时,我的返回值只包含 chambre。

我的第二个问题是“RIGHT JOIN”将每个 chambre 添加到我的查询中,但我想要的只是 chambre 为:“ron.dateFin < ? OR ron.dateDebut > ?” 或尚未与储备者联系的房间。

编辑:这里有一些示例行:

储备:

id |idReservation | idChambre
---+--------------+----------
0  | 1            | 1
Run Code Online (Sandbox Code Playgroud)

房间:

id | idCategorie
---+------------
1  | 1
2  | 2
Run Code Online (Sandbox Code Playgroud)

预订 :

id | date       | dateDebut  | dateFin
---+------------+------------+---------
1  | 03/04/2015 | 01/04/2015 | 06/04/2015
2  | 05/04/2015 | 08/04/2015 | 12/04/2015
Run Code Online (Sandbox Code Playgroud)

我希望我的查询为 chambre 返回 id 1 和 2,但实际上我得到的只是 1

PS:抱歉,英语不是我的母语,但 stackexchange 是一个很棒的网站。

ype*_*eᵀᴹ 5

当您在联接的“错误” *一侧使用表中的列时OUTER,联接通常等同于INNER联接。

* “错误”:联接的右侧LEFT和联接的左侧RIGHT

因此,解决方案通常是将条件从外部连接的移动WHEREON。像这样:

SELECT cre.id,
       rer.idChambre                 -- to actually see NULL
                                     -- where there is no match
FROM   reserver AS rer
       INNER JOIN reservation AS ron
         ON rer.idReservation = ron.id
       RIGHT JOIN chambre AS cre
         ON rer.idChambre = cre.id
         AND (ron.dateFin < ?
             OR ron.dateDebut > ?
             OR (ron.dateFin IS NULL AND ron.dateDebut IS NULL)) ;
Run Code Online (Sandbox Code Playgroud)
  • 另一个问题是= NULL必须转换为IS NULL. Null 很棘手,它不等于任何东西,甚至不等于它们自己。

似乎不太清楚你到底想要什么。您的问题 - 据我从问题和以下评论中了解到 - 是您想要的:

查找未在特定时期(2015 年 4 月 4 日至 2015 年 5 月 4 日)预订的所有房间(房间)?

那么您的查询可以像这样重写:

SELECT cre.id
FROM   chambre AS cre
       LEFT JOIN 
                 reserver AS rer
                 INNER JOIN reservation AS ron
                 ON rer.idReservation = ron.id
                 AND (ron.dateFin > '2015-04-04 00:00:00'
                    AND ron.dateDebut < '2015-05-04 00:00:00')
       ON rer.idChambre = cre.id
WHERE 
    rer.idReservation IS NULL ;
Run Code Online (Sandbox Code Playgroud)

请参阅SQLfiddle-2以了解其他各种编写方式(请尽量避免RIGHT连接。它们使许多习惯于LEFT仅使用外连接的开发人员感到困惑。