문제

나는 이것을 가지고있다 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);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top