2010-06-22 81 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