按顺序值选择单个字段

时间:2013-05-22 17:06:56

标签: sql sql-server tsql

考虑以下两个表:

student_id  score   date
-------------------------
1           10      05-01-2013
2           100     05-15-2013
2           60      05-01-2012
2           95      05-14-2013
3           15      05-01-2011
3           40      05-01-2012


class_id        student_id
----------------------------
1               1
1               2
2               3

我希望得到唯一的class_ids,其中得分高于某个学生的特定阈值,按最新分数排序。

例如,如果我想获得分数为>的类列表80,我会得到class_id 1,因为学生2的最新得分高于> 80.

我如何在t-sql中解决这个问题?

4 个答案:

答案 0 :(得分:3)

你要这个吗?

SELECT DISTINCT
    t2.[class_ID]
FROM
    t1
JOIN t2
    ON t2.[student_id] = t1.[student_id]
WHERE
    t1.[score] > 80

答案 1 :(得分:2)

根据您的日期要求进行修改,然后您可以使用row_number()来获得结果:

select c.class_id
from class_student c
inner join
(
  select student_id,
    score,
    date,
    row_number() over(partition by student_id order by date desc) rn
  from student_score
) s
  on c.student_id = s.student_id
where s.rn = 1
  and s.score >80;

请参阅SQL Fiddle with Demo

或者您可以使用WHERE EXISTS

select c.class_id
from class_student c
where exists (select 1
              from student_score s
              where c.student_id = s.student_id
                and s.score > 80
                and s.[date] = (select max(date)
                                from student_score s1
                                where s.student_id = s1.student_id));

请参阅SQL Fiddle with Demo

答案 2 :(得分:1)

select distinct(class_id) from table2 where student_id in
(select distinct(student_id) from table1 where score > thresholdScore)

答案 3 :(得分:0)

这应该可以解决问题:

SELECT DISTINCT
   CS.Class_ID
FROM
   dbo.ClassStudent CS
   CROSS APPLY (
      SELECT TOP 1 *
      FROM dbo.StudentScore S
      WHERE CS.Student_ID = S.Student_ID
      ORDER BY S.Date DESC
   ) L
WHERE
   L.Score > 80
;

这是另一种方式:

WITH LastScore AS (
   SELECT TOP 1 WITH TIES
   FROM dbo.StudentScore
   ORDER BY Row_Number() OVER (PARTITION BY Student_ID ORDER BY Date DESC)
)
SELECT DISTINCT
   CS.Class_ID
FROM
   dbo.ClassStudent CS
WHERE
   EXISTS (
      SELECT *
      FROM LastScore L
      WHERE
         CS.Student_ID = L.Student_ID
         AND L.Score > 80
   )
;

根据数据和索引,这两个查询可能具有非常不同的性能特征。值得尝试一下,看看是否有人比其他人更优秀。

似乎可能有一些版本的查询,只要找到一个具有必要分数的学生,引擎就会停止查看,但我现在不确定如何实现这一目标。