Return row only if value doesn't exist

后端 未结 2 1899
终归单人心
终归单人心 2020-11-21 06:11

I have 2 tables - reservation:

   id  | some_other_column
   ----+------------------
   1   | value
   2   | value
   3   | value
相关标签:
2条回答
  • 2020-11-21 06:34
    SELECT *
    FROM reservation
    WHERE id NOT IN (select reservation_id
                     FROM reservation_log
                     WHERE change_type = 'cancel')
    

    OR:

    SELECT r.*
    FROM reservation r
    LEFT JOIN reservation_log l ON r.id = l.reservation_id AND l.change_type = 'cancel'
    WHERE l.id IS NULL
    

    The first version is more intuitive, but I think the second version usually gets better performance (assuming you have indexes on the columns used in the join).

    The second version works because LEFT JOIN returns a row for all rows in the first table. When the ON condition succeeds, those rows will include the columns from the second table, just like INNER JOIN. When the condition fails, the returned row will contain NULL for all the columns in the second table. The WHERE l.id IS NULL test then matches those rows, so it finds all the rows that don't have a match between the tables.

    0 讨论(0)
  • 2020-11-21 06:41

    Just for completeness (and I honestly believe it fits better), I encourage you to use a simple NOT EXISTS.

    SELECT * FROM reservation R
    WHERE NOT EXISTS (
      SELECT 1 FROM reservation_log
      WHERE reservation_id = R.id
        AND change_type = 'cancel'
    );
    
    0 讨论(0)
提交回复
热议问题