我有几张桌子,需要加入它们,但有一点麻烦。
表#GradeChange具有学生ID,成绩更改的生效日期以及该日期更改为ON的成绩。表#EventOccurrence包含该学生在特定日期发生的事件。我需要找到学生在活动发生时的成绩。这将是#EventOccurrence生效日期之前#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';
所以这两个表看起来像这样:
预期结果如下:
我玩过“MAX”和“MIN”以及“OVER()”,但不能完全正确。我非常感谢任何帮助!
答案 0 :(得分: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
答案 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)
答案 2 :(得分: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