복붙노트

[SQL] 값이 존재하지 않는 경우에만 반환 행

SQL

값이 존재하지 않는 경우에만 반환 행

나는 2 개 테이블이 - 예약 :

   id  | some_other_column
   ----+------------------
   1   | value
   2   | value
   3   | value

그리고 두 번째 테이블 - reservation_log :

   id  | reservation_id | change_type
   ----+----------------+-------------
   1   | 1              | create
   2   | 2              | create
   3   | 3              | create
   4   | 1              | cancel
   5   | 2              | cancel

나는이 취소뿐만 아니라 예약을합니다 (이 예에서는 유일한 ID 3) 선택해야합니다. 나는 쉽게 change_type의 = 조건을 취소하는 간단한으로 취소 선택할 수 있습니다,하지만 난 여기서 일하지 않는 단순하기 때문에, 취소하지와 사투를 벌인거야.

해결법

  1. ==============================

    1.

    SELECT *
    FROM reservation
    WHERE id NOT IN (select reservation_id
                     FROM reservation_log
                     WHERE change_type = 'cancel')
    

    또는:

    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
    

    첫 번째 버전은보다 직관적이지만, 나는 두 번째 버전은 일반적으로 (당신이에 사용되는 컬럼에 인덱스가 합류 가정) 더 나은 성능을 얻을 생각합니다.

    LEFT 때문에 두 번째 버전의 작품은 반환 첫 번째 테이블의 모든 행에 대한 행 가입하세요. 를 ON 상태가 성공하면, 해당 행은 내부 조인처럼, 두 번째 테이블에서 열을 포함 할 것이다. 조건이 실패하면, 반환 된 행은 두 번째 테이블의 모든 열에 대해 NULL이 포함됩니다. 이 테이블 사이에 일치하지 않는 모든 행을 발견 있도록 l.id은 IS NULL 테스트는, 그 행을 일치합니다.

  2. ==============================

    2.다만 완전성 (그리고 솔직히 더 나은 맞는 생각), 나는 NOT이 존재하는 간단한을 사용하는 것이 좋습니다.

    다만 완전성 (그리고 솔직히 더 나은 맞는 생각), 나는 NOT이 존재하는 간단한을 사용하는 것이 좋습니다.

    SELECT * FROM reservation R
    WHERE NOT EXISTS (
      SELECT 1 FROM reservation_log
      WHERE reservation_id = R.id
        AND change_type = 'cancel'
    );
    
  3. from https://stackoverflow.com/questions/21633115/return-row-only-if-value-doesnt-exist by cc-by-sa and MIT license