开发者

Help needed for writing a Set Based query for finding the highest marks obtained by the students

I have the below table

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 

The desired output should be

Id       Name      Sub1       Sub2      Sub3       Sub4

3        Name3                           100                 

4        Name4     80                                80

5开发者_JAVA百科        Name5      80           70                       

6        Name6                                       80

What I have done so far is

;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

which is giving me the output as

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

Help needed.

Also how can I reduce the number of CTE's?


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  
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜