我如何加入“最新”记录?

时间:2010-06-22 19:38:11

标签: sql tsql sql-server-2000

我在父子关系连接的SQL Server 2000数据库中有两个表。在子数据库中,唯一键由父ID和日期戳组成。

我需要在这些表上进行联接,以便只加入每个孩子的最新条目。

任何人都可以给我任何提示我如何解决这个问题吗?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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