2010-06-22 4 views
1

부모 자식 관계로 조인 된 SQL Server 2000 데이터베이스에 두 개의 테이블이 있습니다. 자식 데이터베이스에서 고유 키는 부모 ID와 날짜 스탬프로 구성됩니다."최근"레코드에 어떻게 가입합니까?

각 하위에 대한 가장 최근 항목 만 가입하도록 이러한 테이블에 대한 조인을 수행해야합니다.

아무에게도 내가 어떻게 할 수있는 힌트를 줄 수 있습니까?

답변

3

다음은 내가 찾은 방법 중 가장 최적화 된 방법입니다. 필자는 여러 구조에 대해이를 테스트했으며이 방법은 다른 접근 방식에 비해 IO가 가장 낮았습니다. 당신은 단지 가장 최근의 각 부모 항목, 부모의 ID, 다음 오른쪽 쉬울 것이다이 포함 된 테이블이 있다면

이 샘플 기사

SELECT t.* 
FROM ARTICLES AS t 
    --Join the the most recent history entries 
     INNER JOIN REVISION lastHis ON t.ID = lastHis.FK_ID 
     --limits to the last history in the WHERE statement 
      LEFT JOIN REVISION his2 on lastHis.FK_ID = his2.FK_ID and lastHis.CREATED_TIME < his2.CREATED_TIME 
WHERE his2.ID is null 
+0

감사합니다. – BenAlabaster

+0

나는 그것을 따라갈 수있어 기쁘다. – Laramie

+0

강 대한 비효율 O (N^2). O (N) 복잡도에 대한 ROW_NUMBER 솔루션을 확인하십시오. – wqw

3

에 마지막으로 개정을 얻을 것?

각 상위 ID에 대해 최대 날짜 스탬프 만 사용하여 하위 테이블을 조인하여 테이블을 만들 수 있습니다. 이런 식으로 뭔가 (당신의 SQL 언어는 다를 수 있음) : 그 부모가 id, 더 높은 타임 스탬프가 존재하지 않은 자식 테이블의 행의 모두를 얻을 수

SELECT t1.* 
    FROM child AS t1 
LEFT JOIN child AS t2 
     ON (t1.parent_id = t2.parent_id and t1.datestamp < t2.datestamp) 
    WHERE t2.datestamp IS NULL 

합니다.

SELECT * 
    FROM parent 
    JOIN (SELECT t1.* 
       FROM child AS t1 
     LEFT JOIN child AS t2 
       ON (t1.parent_id = t2.parent_id and t1.datestamp < t2.datestamp) 
      WHERE t2.datestamp IS NULL) AS most_recent_children 
     ON (parent.id = most_recent_children.parent_id 

또는 직접 부모 테이블을 조인 :

SELECT parent.*, t1.* 
    FROM parent 
    JOIN child AS t1 
     ON (parent.id = child.parent_id) 
LEFT JOIN child AS t2 
     ON (t1.parent_id = t2.parent_id and t1.datestamp < t2.datestamp) 
    WHERE t2.datestamp IS NULL 
1

사용을 기초 참고로이 쿼리를 CTE 정의 부분이 아니라고 당신은에 가입 하위 쿼리에 해당 테이블을 사용할 수 있습니다 질의 - 솔루션은 간단합니다.

use test; 
with parent as (
select 123 pid union all select 567 union all 
select 125 union all 
select 789), 
child as(
select 123 pid,CAST('1/12/2010' as DATE) stdt union all 
select 123 ,CAST('1/15/2010' AS DATE) union all 
select 567 ,CAST('5/12/2010' AS DATE) union all 
select 567 ,CAST('6/15/2010' AS DATE) union all 
select 125 ,CAST('4/15/2010' AS DATE) 
) 
select pid,stdt from(
select a.pid,b.stdt,ROW_NUMBER() over(partition by a.pid order by b.stdt desc) selector 
from parent as a 
left outer join child as b 
on a.pid=b.pid) as x 
where x.selector=1 
+1

다시 SQL Server 2000에서 사용할 수 없습니다 – BenAlabaster