2014-09-15 4 views
0

에서 한 행을 얻기 위해 내가 가지고있는 다음과 같은 두 가지 (간체) 테이블 및 열 :보다 효율적인 방법은 조인 된 테이블

표 1 : 코스 열 : CourseVersion 열 :

표 2 CourseID CourseVersionID, CourseID, Active, UpdateDate, Field1, Field2 ... 등

각 Course 행에 대해 최신 활성 CourseVersion 행을 가져오고 싶습니다. (CourseVersion 행이없는 경우 행 없음). 최신 UpdateDate는 최신 CourseVersionID가 아닐 수 있습니다.

SELECT cv.* FROM Course AS c 
CROSS APPLY(SELECT TOP 1 CourseVersion.* FROM CourseVersion 
    WHERE CourseVersion.CourseID = c.CourseID AND CourseVersion.Active = 1 
    ORDER BY CourseVersion.UpdateDate DESC) AS cv 

이 충분히 잘 작동하지만 느린 :

은 현재이 같은 쿼리가 있습니다.

더 효율적으로 만드는 방법에 대한 일반적인 제안은 무엇입니까?

NB. 각 코스의 최신 버전에 대해 필요한 정보가 무엇인지에 따라 SQL 서버 2012

+1

SQL 서버의 버전은 무엇? 최신 버전에는 사용할 수있는 윈도우 기능이 있습니다. 쿼리 계획은 어떻게 생겼습니까? CTRL-L을 누르면 쿼리 계획이 표시되고 인덱스가 제안됩니다. –

+0

SQL Server 2012. 감사. – johna

답변

1

를 사용하면 간단하게 다음과 같은 사용할 수 있습니다

SELECT cvs.CourseID, MAX(cvs.UpdateDate) 
FROM CourseVersion AS cvs 
WHERE cvs.Active=1 
GROUP BY cvs.CourseID 
+0

이것이 정말로 일반적인 경우이를 감싸고 테이블로 취급하는보기를 만들어야합니다. – UnhandledExcepSean

+0

CourseVersion 테이블의 모든 열이 필요합니다. 이 경우에도 여전히 작동합니까? – johna

+0

max courseversionid와 Max UpdateDate는 항상 같은 행에 있습니까? 그렇다면 MAX (CourseVersionID)를 위 쿼리에 추가하십시오. 그렇지 않다면 요구 사항으로 질문에 정의하십시오. – UnhandledExcepSean

2
with cte as(
    select 
     *, 
     rn = row_number() over(partition by CourseID order by UpdateDate desc) 
    from CourseVersion 
    where 
     Active = 1 
) 
select 
    cv.* --exclude rn 
from course c 
inner join cte cv 
    on cv.CourseID = c.CourseID 
where 
    cv.rn = 1 
+0

나는 이것을 시도하고 작동하지만 실행 시간은 내 테스트 데이터의 경우 약 1100ms이며, 원래의 쿼리는 CROSS APPLY를 사용하여 약 700ms가된다. – johna

+0

코스 테이블에서 아무 것도 필요하지 않으면 cte에서 직접 선택하고 가입을 제거하십시오. 쿼리 속도를 높이는 데 도움이 될 수 있습니다. –

+0

여전히 cte와 no join을 사용하여 같은 시간대에 있습니다. – johna