dsbruqxgt820011351 2014-09-25 18:50
浏览 57
已采纳

MYSQL查找外键不在相关表中的行

I have reservations that can be made in advance. On the day of the reservation, the devices reserved can be checked out.

I have two tables, reservations and checkouts. Reservations have many checkouts.

How would I construct a query that would return all reservations for a particular date that do NOT have associated checkout records?

To put it another way, all rows from reservations where reservation_id column does not contain the reservation's ID?

So far, my best guess is

SELECT * FROM reservations WHERE reservations.id NOT IN (SELECT reservation_id 
FROM checkouts)

But that returns empty. Here's a rough idea what the tables look like

|reservations|  |checkouts         |
|id = 1      |  |reservation_id = 1|
|id = 2      |  |reservation_id = 2|
|id = 3      |  

My result should be reservation 3.

P.S. If php is required, that's fine.

  • 写回答

1条回答 默认 最新

  • dongyuan9109 2014-09-25 19:05
    关注

    Most likely explanation for the query returning no rows is that there are rows in checkouts that have a NULL value for reservation_id. Consider:

    4 NOT IN (2,3,5,NULL,11)
    

    In interpreting this, the NULL value is seen as meaning "unknown what the value is". Is 4 in that list? The answer (coming back from SQL) is basically "unknown" whether 4 matches the "unknown" value in the list.

    If that's what's causing the behavior, you can "fix" your current query by including WHERE reservation IS NOT NULL in the subquery.

    SELECT r.* 
      FROM reservations r
     WHERE r.id NOT IN ( SELECT c.reservation_id 
                           FROM checkouts c
                          WHERE c.reservation_id IS NOT NULL
                       )
    

    This may not be the most efficient approach to returning the specified result. An anti-join is a common pattern for returning this type of result. In your case, that would be an outer join, to return all rows from reservations, along with matching rows from checkouts, and then a predicate in the WHERE clause to filter out all the rows that had a match, leaving us with rows from reservations that didn't have a match.

    For example:

    SELECT r.*
      FROM reservations r
      LEFT
      JOIN checkouts c
        ON c.reservation_id = r.reservation_id
     WHERE c.reservation_id IS NULL
    

    It's also possible to get an equivalent result with a NOT EXISTS with a correlated subquery.

    SELECT r.*
      FROM reservations r
     WHERE NOT EXISTS ( SELECT 1
                          FROM checkouts c
                         WHERE c.reservation_id = r.reservation_id
                       )
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 plotBAPC画图出错
  • ¥30 关于#opencv#的问题:使用大疆无人机拍摄水稻田间图像,拼接成tif图片,用什么方法可以识别并框选出水稻作物行
  • ¥15 Python卡尔曼滤波融合
  • ¥20 iOS绕地区网络检测
  • ¥15 python验证码滑块图像识别
  • ¥15 根据背景及设计要求撰写设计报告
  • ¥20 能提供一下思路或者代码吗
  • ¥15 用twincat控制!
  • ¥15 请问一下这个运行结果是怎么来的
  • ¥15 单通道放大电路的工作原理