>

record 라는 두 개의 테이블이 있습니다  그리고 record_history . 각 레코드에 대해 둘 이상의 히스토리가있을 수 있습니다. 그들은 id 에 의해 가입 될 수 있습니다  그리고 record_id . 나는 모든 record 를 얻고 싶어 최근 record_history 의 항목  데이터. 다음과 같은 검색어를 만들었습니다.

SELECT rec.id, rec.name, rech1.data AS last_history_data
FROM record rec
LEFT OUTER JOIN record_history rech1 ON (rec.id = rech1.record_id)
LEFT OUTER JOIN record_history rech2 ON (rec.id = rech2.record_id AND rech2.ts > rech1.ts)
WHERE rech2.id IS NULL
ORDER BY rec.id DESC

여기서 ts 가 최신 정보를 받고 있습니다 . 중복 ts 가없는 한 작동합니다.  항목. 최근 타임 스탬프가 record_history 에서 반복되는 경우 이 쿼리는 레코드에 대해 둘 이상의 행을 반환합니다. 중복 조인을 제한하기 위해 왼쪽 조인에서 여기에 제한을 적용하는 방법은 무엇입니까?

  • 답변 # 1

    이전 버전의 Postgres에 있지 않으면 이중 조인이 필요하지 않습니다. LATERAL 를 사용하여 동일한 결과를 얻을 수 있습니다.  참여.

    rec.id = rech2.record_id 외에 두 번째 조건을 추가하여 분석법에서 중복 결과를 피할 수 있습니다 . LATERAL 와 함께  가입 방법, LIMIT 사용  어쨌든 피하는 것입니다. 측면 하위 쿼리에서 하나의 행만 반환 될 수 있습니다. 두 번째 조건을 추가하여 선택이 결정적입니다 (동일한 타임 스탬프가있는 두 개 이상의 행에서).

    SELECT rec.id, rec.name, rech.data AS last_history_data
    FROM record AS rec
         LEFT OUTER JOIN LATERAL
         ( SELECT rech.data
           FROM record_history AS rech
           WHERE rec.id = rech.record_id
           ORDER BY rech.ts DESC
                    -- ,rech.id DESC               -- optional
           LIMIT 1 
         ) AS rech
         ON TRUE
    ORDER BY rec.id DESC ;
    
    

    <시간>

    원래의 방법으로이 작업을 수행하는 방법 (2 개의 조인 및 IS NULL )  확인), 당신은 ON 를 변경할 수 있습니다  조건- id 가 있다고 가정   (id) 가되도록 히스토리 테이블의 열  또는 적어도 (ts, id)  독특합니다 :

    LEFT OUTER JOIN record_history rech2 
    ON rec.id = rech2.record_id 
       AND (rech2.ts > rech1.ts OR rech2.ts = rech1.ts AND rech2.id > rech1.id)
    
    

    그건 그렇고, 당신은 그 두 번째 LEFT 를 대체 할 수 있습니다  가입 및 IS NULL   NOT EXISTS 와 확인  동일한 결과와 아마도 유사한 효율성을 가진 하위 쿼리 (또는 심지어 NOT IN )  하위 쿼리는 nullable 열을 추가로 관리해야하지만 권장되지는 않습니다)

  • 이전 sql server 2014 - 복구 모델 변경 사항 찾기
  • 다음 sql server - "값 NULL을 삽입 할 수 없습니다"이지만 NULL 값은 없습니다!