Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 查询以获取“最新”连接到其他具有日期的表_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql server 查询以获取“最新”连接到其他具有日期的表

Sql server 查询以获取“最新”连接到其他具有日期的表,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我有两张桌子,需要把它们连接起来,但有一个转折点 表GradeChange包含学生ID、成绩更改的生效日期以及他们在该日期更改为的成绩。表EventOccurrence包含该学生在特定日期发生的事件。我需要找出事件发生时学生的年级。这将是事件发生生效日期之前发生的等级更改的最新等级。学生可能有多个事件发生,我们可以假设所有学生都至少有一个年级变化条目,日期在他们最早的事件之前 这是DDL: /* If the test table already exists, drop it */

我有两张桌子,需要把它们连接起来,但有一个转折点

表GradeChange包含学生ID、成绩更改的生效日期以及他们在该日期更改为的成绩。表EventOccurrence包含该学生在特定日期发生的事件。我需要找出事件发生时学生的年级。这将是事件发生生效日期之前发生的等级更改的最新等级。学生可能有多个事件发生,我们可以假设所有学生都至少有一个年级变化条目,日期在他们最早的事件之前

这是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一起玩了很多次,但都不太对劲。我非常感谢任何帮助

+1用于包含DDL和样本数据。谢谢,PeeWee。你的答案是第一个,而且有效,所以我选择了它。我非常感谢你的帮助@丹尼尔:注意,如果两个连续的事件之间没有等级变化,它将返回错误的结果。@丹尼尔:再次检查这些时间戳。这实际上是三个答案中的最后一个。:-@乔哈,很明显我是新手吗?我更改了已接受的答案,但将此标记为有用。谢谢大家的帮助!这可能是最直观的答案,因为我不太熟悉合并和外部应用。很有效,谢谢!
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)
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
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