如何获取每个主记录的最后2个详细信息?

时间:2014-02-05 18:16:10

标签: sql ms-access-2010 master-detail

我需要一个MS-Access中的查询,它将返回到每个学生已完成的课程的最后一个。数据看起来像这样:

学生

 ID  | StudentName
 1     John
 2     Bill
 3     Ted
 4     Edward

TrainingDetails

   ID   | StudentID  | ClassName | Date
   1      1            Math        10/10/2012
   2      1            Science     12/10/2012
   3      2            Math        10/10/2012
   4      3            Math        10/10/2012
   5      2            Art         09/10/2012
   6      2            History     02/10/2012
   7      3            Science     12/10/2012
   8      3            History     02/10/2012
   9      4            Music       12/10/2012 

期望输出

Name   | Class     | Date 
John     Science     12/10/2012
John     Math        10/10/2012
Bill     Math        10/10/2012
Bill     Art         09/10/2012
Ted      Science     12/10/2012
Ted      Math        10/10/2012
Edward   Music       12/10/2012

我尝试过使用SELECT TOP 2子句,但总共得到2条记录。我想我需要某种类型的循环来获得每个学生,然后是每个学生的前2个记录,但我无法在一个查询中得到所有这些。

2 个答案:

答案 0 :(得分:1)

如果我们使用自我加入查询,我们可以为每个学生的各个班级分配一个等级(1 =最新):

SELECT 
    t1.StudentID,
    t1.ClassName,
    t1.Date,
    COUNT(*) AS Rank
FROM
    TrainingDetails AS t1
    INNER JOIN
    TrainingDetails AS t2
        ON t2.StudentID = t1.StudentID
            AND t2.Date >= t1.Date
GROUP BY 
    t1.StudentID, 
    t1.ClassName,
    t1.Date
ORDER BY 1, 4

返回

StudentID  ClassName  Date        Rank
---------  ---------  ----------  ----
        1  Science    2012-12-10     1
        1  Math       2012-10-10     2
        2  Math       2012-10-10     1
        2  Art        2012-09-10     2
        2  History    2012-02-10     3
        3  Science    2012-12-10     1
        3  Math       2012-10-10     2
        3  History    2012-02-10     3
        4  Music      2012-12-10     1

我们可以加入[学生]以获取名称,并将结果限制为WHERE Rank <= 2

SELECT
    s.StudentName,
    cr.ClassName,
    cr.Date,
    cr.Rank
FROM
    Students AS s
    INNER JOIN
    (
        SELECT 
            t1.StudentID,
            t1.ClassName,
            t1.Date,
            COUNT(*) AS Rank
        FROM
            TrainingDetails AS t1
            INNER JOIN
            TrainingDetails AS t2
                ON t2.StudentID = t1.StudentID
                    AND t2.Date >= t1.Date
        GROUP BY 
            t1.StudentID, 
            t1.ClassName,
            t1.Date
    ) AS cr
        ON cr.StudentID = s.ID
WHERE cr.Rank <= 2
ORDER BY s.ID, cr.Rank

返回

StudentName  ClassName  Date        Rank
-----------  ---------  ----------  ----
John         Science    2012-12-10     1
John         Math       2012-10-10     2
Bill         Math       2012-10-10     1
Bill         Art        2012-09-10     2
Ted          Science    2012-12-10     1
Ted          Math       2012-10-10     2
Edward       Music      2012-12-10     1

答案 1 :(得分:1)

尝试以下查询。我有一个工作fiddle与SQLServer,但应该适用于Access。您可以根据需要订购结果。

SELECT s.StudentName, t.classname, t.date
FROM Students s
    INNER JOIN TrainingDetails t ON t.StudentID = s.id
WHERE t.Date in (SELECT TOP 2 t2.Date 
                 FROM TrainingDetails t2 
                 WHERE t2.StudentID = s.ID 
                 ORDER BY t2.Date DESC)

(已更正代码以使用Access SQL。)