2011-01-28 111 views
4

我有幾張表,需要加入他們,但有一個轉折。查詢獲取「最近期」加入其他表與日期

表#GradeChange具有學生ID,成績更改的生效日期以及他們在該日期更改爲ON的成績。表#EventOccurrence在某個日期有該學生髮生的事件。我需要找到事件發生時學生的等級。這將是#EradeOccurrence生效日期之前發生的#GradeChange中最新的成績。學生可能有多個EventOccurrences,並且我們可以假設所有學生都至少有一個#GradeChange條目的日期在他們最早的事件之前。

這是DDL:

/* If the test table already exists, drop it */ 
    IF OBJECT_ID('TempDB..#GradeChange','U') IS NOT NULL 
     DROP TABLE #GradeChange; 

    IF OBJECT_ID('TempDB..#EventOccurrence','U') IS NOT NULL 
     DROP TABLE #EventOccurrence;  

/* Create first temp table */ 
CREATE TABLE #GradeChange 
     (
     ID varchar(6), 
     EffectiveDate datetime, 
     Grade varchar(50) 
     );  

/* Populate it */   
INSERT INTO #GradeChange 
    (ID, EffectiveDate, Grade) 
SELECT '678443','Jul 2 2009 11:30PM','Grade 3' UNION ALL 
SELECT '678443','Jan 24 2007 2:40PM','Kindergarten - Half Day' UNION ALL 
SELECT '678443','Jul 4 2007 11:09PM','Grade 1' UNION ALL 
SELECT '678443','Jul 2 2008 11:35PM','Grade 2' UNION ALL 
SELECT '718466','May 18 2009 11:50PM','Pre-Kindergarten' UNION ALL 
SELECT '718466','Jul 2 2009 11:27PM','Kindergarten - Half Day' UNION ALL 
SELECT '718466','Aug 27 2009 11:18PM','Pre-Kindergarten' UNION ALL 
SELECT '718466','Jul 9 2010 11:18PM','Kindergarten - Half Day' UNION ALL 
SELECT '718466','Aug 2 2010 11:14PM','Kindergarten'; 

/* Create 2nd temp table */ 
CREATE TABLE #EventOccurrence 
    (
    ID varchar(6), 
    EventDate datetime 
    ); 

/* Populate it */ 
INSERT INTO #EventOccurrence 
    (ID, EventDate) 
SELECT '718466','Nov 16 2010 12:00AM' UNION ALL 
SELECT '718466','May 20 2009 12:00AM' UNION ALL 
SELECT '678443','Dec 7 2007 12:00AM'; 

所以這兩個表是這樣的:

Tables Example

和預期結果是這樣的:

Results Example

我玩過w ith「MAX」,「MIN」和「OVER()」,但不能完全正確。我非常感謝任何幫助!

+1

1爲包括DDL和樣本數據。 – 2011-01-28 16:31:52

回答

1
select eo.ID, eo.EventDate, gc.Grade 
    from #EventOccurrence eo 
     inner join #GradeChange gc 
      on eo.ID = gc.ID 
       and gc.EffectiveDate = (select max(gc.EffectiveDate) 
              from #GradeChange gc 
              where gc.ID = eo.ID 
               and gc.EffectiveDate <= eo.EventDate) 
+0

這可能是最直觀的答案,因爲我不熟悉合併和外部應用。它的工作原理,謝謝! – Daniel 2011-01-28 17:46:24

2
SELECT * 
FROM #EventOccurrence eo 
OUTER APPLY 
     (
     SELECT TOP 1 Grade 
     FROM #GradeChange gc 
     WHERE gc.id = eo.id 
       AND gc.EffectiveDate <= eo.EventDate 
     ORDER BY 
       gc.EffectiveDate DESC 
     ) gc 
+0

這也適用 - 謝謝! – Daniel 2011-01-28 17:45:33

0
with merged (ID, DDate, Grade, pos) AS 
(
    select ID, DDate, Grade, ROW_NUMBER() over (order by ID, DDate) AS pos FROM (
     select ID, EffectiveDate AS DDate, Grade FROM GradeChange 
     union 
     select ID, EventDate AS DDate, NULL FROM EventOccurrence 
    ) sub 
) 
SELECT m1.ID, m1.DDate, m2.Grade FROM merged m1 LEFT OUTER JOIN merged m2 ON m1.pos = m2.pos+1 WHERE m1.Grade IS NULL 
+0

謝謝,PeeWee。你的答案是第一個,它的工作原理,所以我選擇了它。我非常感謝你的幫助! – Daniel 2011-01-28 17:45:03