문제

"Content"및 "Verseed-Content-Data"라는 1 : N 관계가있는 두 개의 테이블이 있습니다 (예 : 기사 엔티티 및 해당 기사의 모든 버전). 각 "컨텐츠"의 상단 버전을 표시하는보기를 만들고 싶습니다.

현재이 쿼리를 사용합니다 (간단한 하위 쿼리) :

SELECT 
   t1.id, 
   t1.title, 
   t1.contenttext,
   t1.fk_idothertable
   t1.version
FROM mytable as t1
WHERE (version = (SELECT MAX(version) AS topversion
                  FROM mytable
                  WHERE (fk_idothertable = t1.fk_idothertable)))

하위 쿼리는 실제로 특정 항목의 가장 높은 버전을 추출하는 동일한 테이블에 대한 쿼리입니다. 버전의 항목은 동일한 fk_idothertable을 갖습니다.

SQL Server에서 나는 an을 만들려고했다 인덱싱 된보기 이 쿼리 중에서 하위 쿼리가 허용되지 않기 때문에 할 수없는 것 같습니다. 인덱스 뷰. 그래서 ... 여기 내 질문이 있습니다 ...이 쿼리를 조인으로 쿼리로 변환하는 방법을 생각할 수 있습니까?

인덱스 뷰는 다음을 포함 할 수없는 것 같습니다.

  • 하위 쿼리
  • 일반적인 테이블 표현
  • 파생 된 테이블
  • 조항이 있습니다

나는 필사적이다. 다른 아이디어는 환영합니다 :-)

정말 감사합니다!

도움이 되었습니까?

해결책

테이블이 이미 제작 중이지만이를 모델링하는 올바른 방법은 버전 = 0을 영구 버전으로 만들고 항상 이전 자료의 버전을 증가시키는 것입니다. 따라서 새 버전을 삽입하면 다음과 같이 말할 것입니다.

UPDATE thetable SET version = version + 1 WHERE id = :id
INSERT INTO thetable (id, version, title, ...) VALUES (:id, 0, :title, ...)

그러면이 쿼리는 그냥있을 것입니다

SELECT id, title, ... FROM thetable WHERE version = 0

하위 쿼리, 최대 집계가 없습니다. 당신은 항상 현재 버전이 무엇인지 알고 있습니다. 새 레코드를 삽입하기 위해 Max (버전)를 선택할 필요가 없습니다.

다른 팁

아마도 이렇게?

SELECT
  t2.id,
  t2.title,
  t2.contenttext,
  t2.fk_idothertable,
  t2.version
FROM mytable t1, mytable t2
WHERE t1.fk_idothertable == t2.fk_idothertable
GROUP BY t2.fk_idothertable, t2.version
HAVING t2.version=MAX(t1.version)

그냥 거친 추측 ...

Max를 그룹화하는 테이블 별칭으로 만들 수 있습니다.

다음과 같이 보일 수 있습니다.

SELECT 
   t1.id, 
   t1.title, 
   t1.contenttext,
   t1.fk_idothertable
   t1.version
FROM mytable as t1 JOIN
   (SELECT fk_idothertable, MAX(version) AS topversion
   FROM mytable
   GROUP BY fk_idothertable) as t2
ON t1.version = t2.topversion

Ferranb은 가까웠지만 그룹화가 제대로 없다고 생각합니다.

with
latest_versions as (
   select 
      max(version) as latest_version,
      fk_idothertable
   from 
      mytable
   group by 
      fk_idothertable
)
select
  t1.id, 
  t1.title, 
  t1.contenttext,
  t1.fk_idothertable,
  t1.version
from 
   mytable as t1
   join latest_versions on (t1.version = latest_versions.latest_version 
      and t1.fk_idothertable = latest_versions.fk_idothertable);

If SQL Server accepts LIMIT clause, I think the following should work:
SELECT 
   t1.id, 
   t1.title, 
   t1.contenttext,
   t1.fk_idothertable
   t1.version
FROM mytable as t1 ordery by t1.version DESC LIMIT 1;
(DESC - For descending sort; LIMIT 1 chooses only the first row and
DBMS usually does good optimization on seeing LIMIT).

이것이 얼마나 효율적인지 모르겠지만 :

SELECT t1.*, t2.version
FROM mytable AS t1
    JOIN (
        SElECT mytable.fk_idothertable, MAX(mytable.version) AS version
        FROM mytable
    ) t2 ON t1.fk_idothertable = t2.fk_idothertable

이와 같이 ... 하위 퀘리의 'mytable'이 다른 실제 테이블이라고 가정합니다 ... 그래서 나는 그것을 mytable2라고 불렀습니다. 그것이 같은 테이블이라면 여전히 작동하지만 fk_idothertable이 'ID'일 것이라고 생각합니다.


SELECT 
   t1.id, 
   t1.title, 
   t1.contenttext,
   t1.fk_idothertable
   t1.version
FROM mytable as t1
    INNER JOIN (SELECT MAX(Version) AS topversion,fk_idothertable FROM mytable2 GROUP BY fk_idothertable) t2
        ON t1.id = t2.fk_idothertable AND t1.version = t2.topversion

도움이 되었기를 바랍니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top