我在父子关系连接的SQL Server 2000数据库中有两个表。在子数据库中,唯一键由父ID和日期戳组成。
我需要在这些表上进行联接,以便只加入每个孩子的最新条目。
任何人都可以给我任何提示我如何解决这个问题吗?
答案 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