2010-11-08 76 views
0

我有一张来自学生和考试信息的表格,每次学生参加考试时都会在此表中保存一条记录,所以我想从一个考试的学生那里得到最后一次尝试。从学生中选择考试的最后一次尝试

| IdStudent | IdTest | Attempt| 
------------------------------- 
| 1   | 1  | 1  | 
------------------------------- 
| 2   | 1  | 1  | 
------------------------------- 
| 1   | 1  | 2  | 
------------------------------- 
| 2   | 2  | 1  | 

比方说,如果我选择测试号1我想要得到的记录是2和3,如果我选择测试2我想要得到的战绩是4等

希望问题很明显。 在此先感谢您的帮助。

回答

2

下面的SQL会得到你想要的东西:

SELECT IdStudent, IdTest, MAX(Attempt) 
FROM StudentTable 
WHERE IdTest = @TestNumber 
GROUP BY IdStudent, IdTest 
+0

+1 Jeff你可能会考虑在MAX上添加一个别名(尝试) – 2010-11-08 20:25:19

+0

@Conrad:好点。我也没有使用CTE或自我加入,因为表中没有其他数据表示Argons给我们,也没有告诉我们有任何其他数据 – 2010-11-08 20:29:05

+0

是真实的......但他确实说“记录”意味着“行”。谁知道? – Hogan 2010-11-08 20:31:00

2

@杰夫的回答将让你的电话号码,但没有行。如果您需要行中的其他数据,则必须使用子查询或CTE。事情是这样的:

WITH JeffAnswer AS 
(
    SELECT IdStudent, IdTest, MAX(Attempt) AS MaxAttept 
    FROM StudentTable 
    WHERE IdTest = @TestNumber 
    GROUP BY IdStudent, IdTest 
) 
SELECT * 
FROM StudentTable S 
INNER JOIN JeffAnswer J ON 
    S.IdStudent = J.IdStudent AND 
    S.IdTest = J.IdTest AND 
    S.Attempt = J.MaxAttempt 
0

一些替代的方法来杰夫·霍恩比的:

Select ... 
From Table As T1 
Where Exists (
       Select 1 
       From Table As T2 
       Where T2.IdStudent = T1.IdStudent 
        And T2.IdTest =T1.IdTest 
       Having Max(T2.Attempt) = T1.Attempt 
       ) 

如果您正在使用SQL Server 2005+:

With RankedTests As 
    (
    Select IdStudent, IdTest, Attempt, ... 
     , Row_Number() Over (Partition By IdStudent, IdTest 
           Order By Attempt Desc) As Num 
    From Table 
    ) 
Select ... 
From RankedTests 
Where Num = 1 
0

我喜欢的情况下使用ROWNUMBER()之类这是因为稍后更改标准很容易,而且通常比使用GROUP BY更快。

SELECT IdStudent, IdTest, Attempt 
    FROM (
      SELECT IdStudent, IdTest, Attempt, RowId = ROW_NUMBER() OVER(PARTITION BY IdStudent, IdTest ORDER BY IdStudent, IdTest, Attempt Desc) 
      FROM Student 
      WHERE IdTest = @IdTest 
     ) tt 
WHERE tt.RowId = 1