【问题标题】:MySQL full join query displaying records that do not fit criteriaMySQL 全连接查询显示不符合条件的记录
【发布时间】:2020-02-21 10:23:17
【问题描述】:

我正在用 C# 构建一个酒店预订系统,作为我大学毕业后向雇主展示的投资组合项目。

我的主窗体有一个月历对象,一旦单击日期,它将更新包含所有房间的 DataGridView;如果该房间在该日期有预订,则会显示出来。

在 MySQL 数据库中,我使用的 2 个表是“Rooms”和“Reservations”

我将包含带有示例数据的图像,这些图像还显示列标题。

自从我使用 MSSQL 学习 SQL,MySQL 给我带来了一些麻烦。

为了使主窗体正确显示数据,我需要查询返回所有房间,以及该房间在指定日期是否有预订。通过一些研究,我发现完全连接将是正确的连接,因为它显示了两个表中的所有字段。由于 MySQL 不支持完全连接,我找到了一种方法来模拟它使用

SELECT * FROM ROOMS r
LEFT JOIN RESERVATIONS rs ON r.RoomNumber = rs.RoomNumberReserved
UNION
SELECT * FROM ROOMS r
RIGHT JOIN RESERVATIONS rs ON r.RoomNumber = rs.RoomNumberReserved
WHERE
    rs.CheckInDate <= CURRENT_DATE
AND CAST((rs.CheckInDate + rs.NumberOfNights) AS DATE) > CURRENT_DATE

Where 子句基本上说只显示入住日期在该日期之前或之后的预订,以及在该日期之后的退房日期。基本上显示在该日期有效的预订。

但是,示例保留显示 100% 的时间,即使它不符合 where 子句的条件。查询的关键部分的联接运行良好,因为预订显示在正确的房间旁边,但看起来 where 子句没有按预期运行。

我不确定如何进行此操作,因此如果能帮助我走上正轨,我们将不胜感激。

谢谢

Reservations Table Rooms Table

【问题讨论】:

    标签: mysql join where-clause


    【解决方案1】:

    您不需要使用FULL JOIN;来自ROOMSLEFT JOIN 将为您提供ROOMS 中的所有行,无论是否有任何匹配的预订。关键问题是将RESERVATIONS 中的值的任何条件放入ON 条件中,这样您就不会将LEFT JOIN 转换为INNER JOIN(请参阅manual),这不会给您任何没有预订的房间。请注意,您还可以使用 BETWEEN 和日期算术优化日期比较:

    SELECT * FROM ROOMS r
    LEFT JOIN RESERVATIONS rs ON r.RoomNumber = rs.RoomNumberReserved
      AND CURDATE() BETWEEN rs.CheckInDate AND rs.CheckInDate + INTERVAL rs.NumberOfNights - 1 DAY
    

    【讨论】:

    • 效果很好。它也比我所拥有的更紧凑,并且在阅读查询时更容易理解。谢谢
    • @BryanDouglas 别担心 - 我很高兴能帮上忙。
    【解决方案2】:

    您不需要为此使用union。只需在您的日期条件上使用 or 运算符

    SELECT * FROM ROOMS r
    LEFT JOIN RESERVATIONS rs ON r.RoomNumber = rs.RoomNumberReserved
    WHERE 1=1 or 
        current_date() between rs.CheckInDate and cast((rs.CheckInDate + rs.NumberOfNights) AS date)
    

    【讨论】:

      【解决方案3】:

      您需要将where 子句应用于子选择中union 的结果。另一种方法是将 where 子句应用于个人 select。 所以你的查询变成了-

      SELECT * FROM ROOMS r
      LEFT JOIN RESERVATIONS rs ON r.RoomNumber = rs.RoomNumberReserved
      WHERE
      rs.CheckInDate <= CURRENT_DATE
      AND CAST((rs.CheckInDate + rs.NumberOfNights) AS DATE) > CURRENT_DATE
      
      UNION
      
      SELECT * FROM ROOMS r
      RIGHT JOIN RESERVATIONS rs ON r.RoomNumber = rs.RoomNumberReserved
      WHERE
      rs.CheckInDate <= CURRENT_DATE
      AND CAST((rs.CheckInDate + rs.NumberOfNights) AS DATE) > CURRENT_DATE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-26
        • 2012-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多