2010-06-22 37 views
1

我有一个由父子关系连接的SQL Server 2000数据库中有两个表。在子数据库中,唯一键由父ID和日期戳组成。如何加入“最新”记录?

我需要在这些表上做一个连接,这样每个孩子只有最新的条目才能加入。

任何人都可以给我任何提示,我可以怎么做呢?

回答

3

这是我发现的最优化的方式。我对几个结构进行了测试,与其他方法相比,这种方法具有最低的IO。

此示例将获得最后修订的文章

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 2010-06-22 20:02:51

+0

我很高兴我可以通过它。 – Laramie 2010-06-22 20:21:17

+0

Mighty inefficient O(N^2)。查看ROW_NUMBER解决方案的O(N)复杂性。 – wqw 2010-06-22 21:25:38

3

如果你有这只是包含在最近为每个父项,父母的ID,那么这将是容易的,正确的表?

您可以通过将自己的子表连接在一起来创建一个表格,仅为每个父ID使用最大日期戳记。像这样的东西(你的SQL方言可能会有所不同):

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 

,让你的所有行中对于没有更高的时间戳存在的子表,对于父ID。您可以使用表子查询加入到:

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 2010-06-23 16:07:24