编写基于Set的查询以查找学生获得的最高分数所需的帮助

时间:2010-12-30 12:34:41

标签: sql-server sql-server-2005

我有下表

declare @t table
(id int identity, name varchar(50),sub1 int,sub2 int,sub3 int,sub4 int)

insert into @t
select 'name1',20,30,40,50 union all
select 'name2',10,30,40,50 union all
select 'name3',40,60,100,50 union all
select 'name4',80,30,40,80 union all
select 'name5',80,70,40,50 union all
select 'name6',10,30,40,80 

所需的输出应为

Id       Name      Sub1       Sub2      Sub3       Sub4

3        Name3                           100                 

4        Name4     80                                80

5        Name5      80           70                       

6        Name6                                       80

到目前为止,我所做的是

;with cteSub1 as
(
    select rn1 = dense_rank() over(order by sub1 desc),t.id,t.name,t.sub1 from @t t
)
,cteSub2 as
(
    select rn2 = dense_rank() over(order by sub2 desc),t.id,t.name,t.sub2 from @t t
)
,cteSub3 as
(
    select rn3 = dense_rank() over(order by sub3 desc),t.id,t.name,t.sub3 from @t t
)
,cteSub4 as
(
    select rn4 = dense_rank() over(order by sub4 desc),t.id,t.name,t.sub4 from @t t
)
select x1.id,x2.id,x3.id,x4.id ,x1.sub1,x2.sub2,x3.sub3,x4.sub4 from  (select c1.id,c1.sub1 from cteSub1 c1 where rn1 =1) as x1
full join (select c2.id,c2.sub2 from cteSub2 c2 where rn2 =1)x2
on x1.id = x2.id
full join (select c3.id,c3.sub3 from cteSub3 c3 where rn3 =1)x3
on x1.id = x3.id
full join (select c4.id,c4.sub4 from cteSub4 c4 where rn4 =1)x4
on x1.id = x4.id

给出了输出

id  id  id  id  sub1    sub2    sub3    sub4
5   5   NULL    NULL    80  70  NULL    NULL
4   NULL    NULL    4   80  NULL    NULL    80
NULL    NULL    3   NULL    NULL    NULL    100 NULL
NULL    NULL    NULL    6   NULL    NULL    NULL    80

需要帮助。

另外,我如何减少CTE的数量?

1 个答案:

答案 0 :(得分:2)

WITH cte1
     AS (SELECT *
         FROM   @t UNPIVOT (grade FOR sub IN (sub1, sub2, sub3, sub4) )AS unpvt)
,
     cte2
     AS (SELECT *,Rank() OVER (PARTITION BY sub ORDER BY grade DESC) rn
         FROM   cte1)
SELECT *
FROM   cte2 PIVOT(MAX (grade) FOR sub IN (sub1, sub2, sub3, sub4) ) AS pvt
WHERE  rn = 1