2011-01-28 10 views
4

私はいくつかのテーブルがあり、それらに参加する必要がありますが、ひねりを加えます。「最新のもの」を取得するためのクエリ

表#GradeChangeには、学生IDと、成績の変更の有効日と、その日にONに変更された成績があります。表#EventOccurrenceには、特定の日付にその生徒に発生したイベントがあります。私は、イベントが発生したときに学生がどのような成績を取ったのかを知る必要があります。これは、#EventOccurrence Effective Dateの前に発生した#GradeChangeからの最新グレードです。生徒には複数のイベント出席があり、すべての生徒に最も古いイベントの前に日付が付いた#GradeChangeエントリが1つ以上あると想定できます。

これは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'; 

ので、2つのテーブルは次のようになります。

Tables Example

及び予想される結果は次のようになります。

Results Example

私はwをプレイしました"MAX"、 "MIN"、 "OVER()"のように表示されますが、正しく表示されません。助けてくれてありがとう! DDLとサンプルデータを含むため

+1

+1。 –

答えて

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

私はMERGEDとOUTER APPLYに慣れていないので、これはおそらく最も直感的な答えです。それは動作します、ありがとう! – Daniel

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

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

+0

@Daniel:2つの連続したイベントがあって間に成績の変更がない場合は、間違った結果を返すことに注意してください。 – Quassnoi

+0

@Daniel:タイムスタンプをもう一度確認してください。これは実際には3つの回答のうちの最後のものでした。 :-) –

関連する問題