programing

SQL 방법 관련 테이블에서 최신만 선택

closeapi 2023. 7. 30. 17:48
반응형

SQL 방법 관련 테이블에서 최신만 선택

모든 항목을 선택할 수 있는 요청 테이블이 있고, 최신 보고서만 선택할 수 있는 위치 보고서 관련 테이블이 있습니다.

아래 SQL은 포지션 보고서가 하나만 있으면 제가 원하는 것을 해주지만, 더 많아지자마자 SQL은 제가 어떤 것을 원하는지 전혀 모르는 것으로 알고 있습니다.하지만 저는 그것을 어떻게 명시해야 할지 모르겠습니다.

SELECT
r.id mission_id,
report.Timestamp as reportTimestamp,
report.Latitude as reportLat,
report.Longitude as reportLng,
FROM Requests r
LEFT JOIN PositionReports report ON r.id = report.RequestId

업데이트 -----------------

이 MySQL JOIN의 안내를 받아 가장 최근 행에만 참여하시겠습니까?저는 가장 최근의 것을 가져올 수 있었습니다. 하지만 새로운 문제는 제가 실제로 위치 보고서가 있는 그런 임무들만 검색된다는 것입니다.

    WHERE report.Id = (
        SELECT MAX(Id)
        FROM PositionReports
        WHERE RequestId = r.Id
    )";

보고서 테이블에도 항목이 없는 모든 항목을 검색할 수 있는 방법이 있습니까?외부 조인을 시도했지만 차이가 없습니다...

MySQL 데이터베이스입니다(테스트 환경은 MariaDB이지만 프로덕션은 MySQL(DigitalOcean)입니다).

사전 집계를 제안할 때, 하나의 SQL 쿼리만으로는 달성하고자 하는 목표를 달성할 수 없음을 의미합니까?

표본 데이터 ---------------------------

RequestsTable에 ID 178과 179의 두 항목이 포함되어 있다고 가정해 보겠습니다.

이드 기타 자료
178 로렘...
179 ipsum...

이 중 179개의 행만 positionReports 표에 일치하는 행이 있습니다.

PositionReports 테이블에는 다음이 포함됩니다.

이드 requestId 타임스탬프 위도 경도
2 179 123456700 56.5 11.9
1 179 123456789 57.0 12.0

원하는 출력(쿼리가 둘 다 검색해야 함).타임스탬프에서 가장 높은 값을 가진 보고서 위치를 선택하는 것이 이상적이지만, Id를 정렬하면 보고서를 승인할 때 연대순으로 적용되므로 이 구현에도 효과가 있습니다.

requestId 타임스탬프 위도 경도
178
179 123456789 57.0 12.0

덕분에 최소한 작동할 수 있었던 것 같습니다. 첫 번째 테이블의 모든 데이터를 반환하고, 두 번째 테이블의 데이터가 있으면 하나만 반환합니다.

이 솔루션이 얼마나 효율적인지(또는 리소스 호깅이라고 해야 할지) 잘 모르겠습니다.

        SELECT
        r.id as id,
        reports.Timestamp as reportTimestamp,
        reports.Latitude as reportLat,
        reports.Longitude as reportLng,
        FROM Requests r
        LEFT JOIN 
        
        (SELECT 
          c.* 
        FROM
          PositionReports c 
          LEFT JOIN PositionReports d 
            ON c.RequestId = d.RequestId 
            AND c.Timestamp < d.Timestamp 
        WHERE d.RequestId IS NULL) reports
        
        ON r.id = reports.RequestId 

리소스 소비에 대한 클레임 없음 - RANK 창 기능을 사용하는 대체 접근 방식:

SELECT
  r.id as id,
  reports.Timestamp as reportTimestamp,
  reports.Latitude as reportLat,
  reports.Longitude as reportLng
FROM RequestsTable r
LEFT JOIN (
  SELECT
    *,
    RANK() OVER (PARTITION BY RequestId ORDER BY Timestamp DESC) as rnk
  FROM PositionReports
  ) reports
  on reports.RequestId = r.id
  and reports.rnk = 1
;

실제로 보기: DB Fiddle.

조정/자세한 내용이 필요한 경우 의견을 제시해 주십시오.

보고서 테이블에도 항목이 없는 모든 항목을 검색할 수 있는 방법이 있습니까?

의 코드의 이 당의코문당사있것입다니다는고용하를 입니다.where필터링 절 - 그래서 이것은 에서 일치하지 않는 레코드를 제거합니다.left join을 필링을다이수있다니습으로 .on다음과 같은 조인 절:

select
    r.id mission_id,
    pr.Timestamp as reportTimestamp,
    pr.Latitude as reportLat,
    pr.Longitude as reportLng
from Requests r
left join PositionReports pr 
    on  pr.RequestId = r.id
    and pr.id = ( select max(pr1.id) from PositionReports pr1 where pr1.RequestId = r.Id)

이제 두 번째 조건이 적용되므로 첫 번째 조인 조건이 중복된 것처럼 보인다는 것을 알 수 있습니다. 이 정도면 충분합니다.

select
    r.id mission_id,
    pr.Timestamp as reportTimestamp,
    pr.Latitude as reportLat,
    pr.Longitude as reportLng
from Requests r
left join PositionReports pr 
    on pr.id = ( select max(pr1.id) from PositionReports pr1 where pr1.RequestId = r.Id)

마지막으로, MySQL 8.0.13 이상을 실행 중인 경우, 이것은 측면 결합에 매우 적합한 위치로 보입니다.

select r.id mission_id,
    pr.Timestamp as reportTimestamp,
    pr.Latitude as reportLat,
    pr.Longitude as reportLng
from Requests r
left join lateral (
    select pr.*
    from PositionReports pr 
    where pr.RequestId = r.Id
    order by id desc limit 1
) pr on 1

하위 쿼리는 외부 쿼리와 상관 관계가 있으며, 검색 중인 레코드를 인덱스와 함께 직접 반환합니다.PositionReports(RequestId, id desc)이것은 효율적인 해결책이 될 것입니다.

언급URL : https://stackoverflow.com/questions/76615108/how-to-sql-select-only-most-recent-from-related-table

반응형