2

考虑以下两个表:

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

4 回答 4

3

你问这个吗?

SELECT DISTINCT
    t2.[class_ID]
FROM
    t1
JOIN t2
    ON t2.[student_id] = t1.[student_id]
WHERE
    t1.[score] > 80
于 2013-05-22T17:09:08.860 回答
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

或者您可以使用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

于 2013-05-22T17:12:48.997 回答
1
select distinct(class_id) from table2 where student_id in
(select distinct(student_id) from table1 where score > thresholdScore)
于 2013-05-22T17:10:31.710 回答
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
   )
;

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

似乎可能存在某个版本的查询,其中引擎一旦找到一个具有必要分数的学生就会停止查找,但我目前不确定如何实现这一点。

于 2013-05-22T17:57:26.280 回答