通过比较一行中的不同列来选择三个最高值?

时间:2015-01-19 07:54:54

标签: sql sql-server

为简单起见,我认为我有一个查询,它根据student_id返回一行,它包含六个测验标记,其中列名称如Quiz1 Quiz2 Quiz3 Quiz4 Quiz5 Quiz6。

我想只选择学生安全的前3个最高分,然后取其平均值,然后将该平均值与另一列“Pass_Avg”进行比较 如果前3个测验标记的平均值大于等于“Pass_Avg”的值,那么只需将结果列的值改为'P',否则为'F'。

所以我试图通过做这样的事情来获得最高价值

SELECT
CASE

     WHEN Quiz1 >= Quiz2 AND Quiz1 >= Quiz3 and Quiz1 >= Quiz4 and Quiz1 >= Quiz5 and Quiz1 >= Quiz6 THEN Quiz1
     WHEN Quiz2 >= Quiz1 AND Quiz2 >= Quiz3 and Quiz2 >= Quiz4 and Quiz2 >= Quiz5 and Quiz2 >= Quiz6 THEN  Quiz2
     WHEN Quiz3 >= Quiz1 AND Quiz3 >= Quiz2 and Quiz3 >= Quiz4 and Quiz3 >= Quiz5 and Quiz3 >= Quiz6 THEN  Quiz3
     WHEN Quiz4 >= Quiz1 AND Quiz4 >= Quiz2 and Quiz4 >= Quiz3 and Quiz4 >= Quiz5 and Quiz4 >= Quiz6 THEN  Quiz4
     WHEN Quiz5 >= Quiz1 AND Quiz5 >= Quiz2 and Quiz5 >= Quiz3 and Quiz5 >= Quiz4 and Quiz5 >= Quiz6 THEN  Quiz5
     WHEN Quiz6 >= Quiz1 AND Quiz6 >= Quiz2 and Quiz6 >= Quiz3 and Quiz6 >= Quiz4 and Quiz6 >= Quiz5 THEN  Quiz6
     ELSE Quiz1
    END AS Highest from dbo.Student where student_id= '01' 

任何人都可以建议我应该如何尝试这样做,因为我很难获得第二和第三高的价值......

2 个答案:

答案 0 :(得分:0)

做这样的事情:

select Quiz1,'Quiz1' from dbo.Student where student_id= '01'
UNION ALL
select Quiz2,'Quiz2' from dbo.Student where student_id= '01'
UNIONA ALL
...
order by 1 desc

获得前三名? SQL Server是否支持LIMIT?或者只是TOP?

尝试使用TOP:

select top 3 * from
(
    select Quiz1,'Quiz1' from dbo.Student where student_id= '01'
    UNION ALL
    select Quiz2,'Quiz2' from dbo.Student where student_id= '01'
    UNION ALL
    ...
    order by 1 desc
)

可以工作......

答案 1 :(得分:0)

问题在于您的数据库设计。你应该有一个带有student_id和quiz_id的表student_quiz。相反,您在列中进行了测验,这使得访问更加复杂。使用UNION ALL模拟更好的数据库设计。 (我们将随之选择pass_avg以便稍后使用)。然后给出每个学生的记录行号,其中1是最高测验结果,2是第二个,依此类推。然后选择最好的三个并进行聚合。

select
  student_id, 
  sum(quiz),
  min(pass_avg),
  case when sum(quiz) / 3 >= min(pass_avg) then 'yes' else 'no' end as passed
from
(
  select 
    student_id, 
    quiz,
    pass_avg,
    row_number() over (partition by student_id order by quiz desc) as rn
  from
  (
    select student_id, quiz1 as quiz, pass_avg from student 
    union all
    select student_id, quiz2 as quiz, pass_avg from student 
    union all
    select student_id, quiz3 as quiz, pass_avg from student 
    union all
    select student_id, quiz4 as quiz, pass_avg from student 
    union all
    select student_id, quiz5 as quiz, pass_avg from student 
    union all
    select student_id, quiz6 as quiz, pass_avg from student 
  )
where rn in (1,2,3)
group by student_id
order by student_id