제한된 하위 퀘스트에 가입 하시겠습니까?
-
05-07-2019 - |
문제
나는 이것을 가지고있다 releases
SQLITE3 데이터베이스의 테이블, 각 릴리스 버전의 응용 프로그램 버전을 나열합니다.
|release_id|release_date|app_id|
|==========|============|======|
| 1001| 2009-01-01 | 1|
| 1003| 2009-01-01 | 1|
| 1004| 2009-02-02 | 2|
| 1005| 2009-01-15 | 1|
따라서 각 APP_ID에 대해 여러 행이 있습니다. 다른 테이블이 있고 apps
:
|app_id|name |
|======|========|
| 1|Everest |
| 2|Fuji |
"최신"이 (a) 최신 릴리스 _date를 의미하는 응용 프로그램의 이름과 최신 릴리스를 표시하고자합니다.
개별 응용 프로그램을 위해이 작업을 수행 할 수 있습니다.
SELECT apps.name,releases.release_id,releases.release_date
FROM apps
INNER JOIN releases
ON apps.app_id = releases.app_id
WHERE releases.release_id = 1003
ORDER BY releases.release_date,releases.release_id
LIMIT 1
그러나 물론 그 순서는 전체 선택 쿼리에 적용되며 Where 절을 종료하면 여전히 한 행만 반환합니다.
작은 데이터베이스의 원샷 쿼리이므로 느린 쿼리, 온도 테이블 등이 괜찮습니다.
해결책
이것은 SQLITE3가 지원하지 않는 분석 기능 Row_Number ()와 쉽게 수행 할 수 있습니다. 그러나 이전 답변에서 주어진 것보다 조금 더 유연한 방식으로 할 수 있습니다.
SELECT
apps.name,
releases.release_id,
releases.release_date
FROM apps INNER JOIN releases
ON apps.app_id = releases.app_id
WHERE NOT EXISTS (
-- // where there doesn't exist a more recent release for the same app
SELECT * FROM releases AS R
WHERE R.app_id = apps.app_id
AND R.release_data > releases.release_data
)
예를 들어, "최신"을 정의하는 여러 주문 열이 있다면 Max는 귀하에게 효과가 없지만 "최신"의 더 복잡한 의미를 포착하기 위해 존재 하위 쿼리를 수정할 수 있습니다.
다른 팁
이것은 "그룹당 가장 큰 N"문제입니다. StackoverFlow에서 일주일에 여러 번 등장합니다.
나는 보통 @steve kass '와 같은 솔루션을 사용합니다. 대답, 그러나 나는 하위 쿼리없이 그것을한다 (나는 수년 전에 mySQL 4.0과 함께 습관을 들었다.
SELECT a.name, r1.release_id, r1.release_date
FROM apps a
INNER JOIN releases r1
LEFT OUTER JOIN releases r2 ON (r1.app_id = r2.app_id
AND (r1.release_date < r2.release_date
OR r1.release_date = r2.release_date AND r1.release_id < r2.release_id))
WHERE r2.release_id IS NULL;
내부적으로 이것은 아마도 동일하게 최적화 될 것입니다 NOT EXISTS
통사론. 쿼리를 분석 할 수 있습니다 EXPLAIN
확인하십시오.
당신의 의견을 다시, 당신은 단지 시험을 건너 뛸 수 있습니다. release_date
왜냐하면 release_id
연대순 릴리스를 설정하는 데 유용하며 독특하다고 가정하므로 쿼리를 단순화합니다.
SELECT a.name, r1.release_id, r1.release_date
FROM apps a
INNER JOIN releases r1
LEFT OUTER JOIN releases r2 ON (r1.app_id = r2.app_id
AND r1.release_id < r2.release_id)
WHERE r2.release_id IS NULL;
못 생겼지 만 효과가있을 것 같아요
select apps.name, (select releases.release_id from releases where releases.app_id=apps.app_id order by releases.release_date, releases.release_id), (select releases.release_date from releases where releases.app_id=apps.app_id order by releases.release_date, releases.release_id) from apps order by apps.app_id
나는 두 열을 하나의 임베디드 셀렉션으로 가져갈 수있는 방법이 있기를 바랍니다. 그러나 나는 그것을 모른다.
노력하다:
SELECT a.name,
t.max_release_id,
t.max_date
FROM APPS a
JOIN (SELECT t.app_id,
MAX(t.release_id) 'max_release_id',
t.max_date
FROM (SELECT r.app_id,
r.release_id,
MAX(r.release_date) 'max_date'
FROM RELEASES r
GROUP BY r.app_id, r.release_id)
GROUP BY t.app_id, t.max_date) t
두 번째 시도. ID가 단조롭게 증가하고 오버플로가 발생하지 않는다고 가정하면 날짜를 무시하고 그냥 할 수 있습니다.
SELECT apps.name, releases.release_id, releases.release_date
FROM apps INNER JOIN releases on apps.app_id = releases.app_id
WHERE releases.release_id IN
(SELECT Max(release_id) FROM releases
GROUP BY app_id);