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
'programing' 카테고리의 다른 글
AJAX 호출의 오류를 어떻게 처리합니까? (0) | 2023.07.30 |
---|---|
Firebase용 Cloud Functions로 업로드된 파일에서 다운로드 URL 가져오기 (0) | 2023.07.30 |
NumPy 배열의 모든 셀에서 함수의 효율적인 평가 (0) | 2023.07.25 |
PHP: 파일에서 특정 행 읽기 (0) | 2023.07.25 |
파이썬에서 사용자 이름과 암호를 안전하게 저장해야 하는데, 옵션은 무엇입니까? (0) | 2023.07.25 |