想从sql server中的表中查找得分主题的名称和最大分数

时间:2017-01-25 16:38:07

标签: sql sql-server sql-server-2008 tsql

嗨我有一个表变量,我想找到每个学生的最高得分主题。

declare @test1 table (name varchar(50), english int, math int, science int)

insert into @test1(name, english, math, science)
select 'A', 50, 90, 70
union all 
select 'B', 60, 80, 65
union all 
select 'C' , 80,65, 70
union all 
select 'D', 70, 75, 89

如果有人可以帮助我,那将是可观的。

3 个答案:

答案 0 :(得分:4)

这是一个诀窍

SELECT TOP 1 WITH ties NAME,
                       sub_name,
                       mark
FROM   @test1
       CROSS apply (VALUES(english,'english'),
                          (math,'math'),
                          (science,'science'))tc(mark, sub_name)
ORDER  BY Row_number()OVER(partition BY NAME ORDER BY mark DESC) 

或使用丑陋的CASE语句,但这比Cross Apply

更好
SELECT NAME,
       sub_name,
       CASE sub_name
         WHEN 'english' THEN english
         WHEN 'math' THEN math
         ELSE science
       END mark
FROM   (SELECT *,
               CASE
                 WHEN english > math AND english > science THEN 'english'
                 WHEN english < math AND math > science THEN 'math'
                 ELSE 'science'
               END AS sub_name
        FROM   @test1) a 

答案 1 :(得分:2)

既然你不想申请,也许是UNPIVOT

Declare @test1 table (name varchar(50), english int, math int, science int)
insert into @test1(name, english, math, science)
select 'A', 50, 90, 70 union all select 'B', 60, 80, 65 union all  select 'C' , 80,65, 70 union all  select 'D', 70, 75, 89

Select Top 1 with Ties 
       Name,SubjectName,Score
From   @test1 A
unpivot ( Score for SubjectName in ( english, math, science) ) u
Order by Row_number() Over (Partition By Name Order By Score Desc) 

Retruns

Name    SubjectName  Score
A       math         90
B       math         80
C       english      80
D       science      89

答案 2 :(得分:1)

Prdp的Cross Apply将是我的第一选择(+1)。但是,如果您不想指定所有字段,请通过XMLCROSS APPLY(或两个)

进行更加动态的处理
Declare @test1 table (name varchar(50), english int, math int, science int)
insert into @test1(name, english, math, science)
select 'A', 50, 90, 70 union all select 'B', 60, 80, 65 union all  select 'C' , 80,65, 70 union all  select 'D', 70, 75, 89

Select Top 1 with Ties 
       A.Name
      ,C.*
 From  @test1 A
 Cross Apply (Select XMLData= cast((Select A.* for XML Raw) as xml)) B
 Cross Apply (
                Select Item   = attr.value('local-name(.)','varchar(100)')
                      ,Value  = attr.value('.','varchar(max)') 
                 From  B.XMLData.nodes('/row') as A(r)
                 Cross Apply A.r.nodes('./@*') AS B(attr)
                 Where attr.value('local-name(.)','varchar(100)') not in ('name','otherfields')  --<< field names are case sensitive
             ) C
 Order by Row_number() Over (Partition By Name Order By Value Desc) 

返回

Name    Item    Value
A       math    90
B       math    80
C       english 80
D       science 89