如何迭代此SQL查询?

时间:2012-10-26 18:51:37

标签: sql sql-server sql-server-2008 sql-server-2008-r2

我有这个问题:

SELECT TOP 1 A.ExamTemplateId, A.Id AS AnsweredTestId, AVG(B.Score) AS AvgScore, A.[Date]
FROM AnsweredTest AS A
INNER JOIN AnsweredWorksheet AS B ON (A.Id = B.AnsweredTestId)
WHERE A.StudentId = 'OPA-3DKCL2' AND A.ExamTemplateId = 1
GROUP BY A.Id, A.ExamTemplateId, A.[Date]
ORDER BY AvgScore DESC

请检查我的WHERE条件是否收到静态编号。查询结果为:

示例1

示例2 enter image description here

这是正确的!但现在,我想显示ExamTemplate表中的所有记录。但现在我不知道如何实现这一目标。我在想创建一个函数,但我不确定,这只是一个想法。

我想收到的最终结果是最后记录的结合:

1   1   0.7 2012-10-21 19:50:11.697
2   10  0.555555555555556   2012-10-22 18:58:24.163

提前致谢。

更新:

我用黄色突出显示了我感兴趣的行。我在最后一个查询TOP 1中设置了因为我想获得ExamTemplateId的最高平均分数。这就是全部。

enter image description here

3 个答案:

答案 0 :(得分:3)

听起来您想要用值列表替换A.ExamTemplateId = 1。如果是这样,那么你应该可以使用类似于以下内容的东西:

SELECT A.ExamTemplateId, 
  A.Id AS AnsweredTestId, 
  AVG(B.Score) AS AvgScore, 
  A.[Date]
FROM AnsweredTest AS A
INNER JOIN AnsweredWorksheet AS B 
  ON (A.Id = B.AnsweredTestId)
WHERE A.StudentId = 'OPA-3DKCL2' 
  AND A.ExamTemplateId IN (SELECT ExamTemplateId -- use a SELECT statement to get all template id
                           FROM ExamTemplateTable)
GROUP BY A.Id, A.ExamTemplateId, A.[Date]
ORDER BY AvgScore DESC

如果您只想要一个值,那么您可以使用以下内容:

select ExamTemplateId,
    AnsweredTestId,
    AvgScore,
    [Date]
from 
(
  select ExamTemplateId,
    AnsweredTestId,
    AvgScore,
    [Date],
    row_number() over(partition by ExamTemplateId order by AvgScore) rn
  from
  (
    SELECT A.ExamTemplateId, 
      A.Id AS AnsweredTestId, 
      AVG(B.Score) AS AvgScore, 
      A.[Date]
    FROM AnsweredTest AS A
    INNER JOIN AnsweredWorksheet AS B 
      ON (A.Id = B.AnsweredTestId)
    WHERE A.StudentId = 'OPA-3DKCL2' 
      AND A.ExamTemplateId IN (SELECT ExamTemplateId -- use a SELECT statement to get all template id
                               FROM ExamTemplateTable)
    GROUP BY A.Id, A.ExamTemplateId, A.[Date]
  ) sc
) mx
where rn = 1

答案 1 :(得分:1)

使用分区。

With t AS (
    SELECT A.ExamTemplateId, A.Id AS AnsweredTestId, AVG(B.Score) AS AvgScore, A.[Date] 
    FROM AnsweredTest AS A
    INNER JOIN AnsweredWorksheet AS B ON (A.Id = B.AnsweredTestId)
    WHERE A.StudentId = 'OPA-3DKCL2' --AND A.ExamTemplateId in (...)
    GROUP BY A.Id, A.ExamTemplateId, A.[Date]
)
, w AS (
    SELECT *, 
        ROW_NUMBER() OVER (PARTITION BY ExamTemplateId ORDER BY AvgScore DESC) rank
    FROM t 
)
SELECT * FROM w 
WHERE rank = 1

答案 2 :(得分:0)

起初我以为你想看到所有的学生,但我想你想要超过所有考试模板 - 任何理由你不能只删除前1个过滤器并从中取出考试模板? 平均值将按照考试模板计算,我想你想要的是什么。

SELECT A.ExamTemplateId, A.Id AS AnsweredTestId, AVG(B.Score) AS AvgScore, A.[Date]
FROM AnsweredTest AS A
INNER JOIN AnsweredWorksheet AS B ON (A.Id = B.AnsweredTestId)
WHERE A.StudentId = 'OPA-3DKCL2' 
GROUP BY A.Id, A.ExamTemplateId, A.[Date]
ORDER BY AvgScore DESC`