按升序排列所选列

时间:2015-12-30 22:22:40

标签: sql-server sql-server-2008

我有一张这样的桌子;

Reg_No      Student_Name         col1    col2    col3
----------- -------------------- ------ ------ ------
101         Kevin                77          94          78
102         Andrew               91          81          17
103         Scott                46          83          28

如何选择col1,col2,col3并将col1,col2,col3中选定的值从每行按升序排列,但保持表的访问顺序,如下所示?

Reg_No      Student_Name         Lowest    Middle    Highest
----------- ------------------- --------- --------- ---------
101         Kevin                77          78          94
102         Andrew               17          81          91
103         Scott                28          46          83

我正在使用MSSQL Server 2008 R2

3 个答案:

答案 0 :(得分:3)

这在SQL Server中有点痛苦。一种方法是取消数据转换然后重新转动。我倾向于使用条件聚合来做到这一点:

select Reg_No, Student_Name,
       max(case when seqnum = 1 then col end) as Lowest,
       max(case when seqnum = 2 then col end) as Middle,
       max(case when seqnum = 3 then col end) as Highest
from (select t.*, v.col,
             row_number() over (partition by Reg_No, Student_Name order by v.col) as seqnum
      from likethis t cross apply
           (values (t.col1), (t.col2), (t.col3)
           ) v(col)
     ) t
group by Reg_No, Student_Name;

如果您尝试使用case语句执行此操作,则会因为可能的关联和NULL值而变得非常复杂。

答案 1 :(得分:0)

您需要规范化您的数据,但在此之前:

with temp (ColNo, Reg_No, Student_Name, col) as
   select 1, Reg_No, Student_Name, col1
   from Students
   union all
   select 2, Reg_No, Student_Name, col2
   from Students
   union all
   select 3, Reg_No, Student_Name, col3
   from Students;


select 
   min(t1.col) as Lowest,
   max(t2.col) as Middle
   max(t1.col) as Highest
from temp t1
join t2
on t1.Reg_No = t2.Reg_No
   and t1.Student_Name = t1.Student_Name
   and t1.ColNo <> t2.ColNo  -- don't match on self
   and t1.col >= t2.col      -- don't include the max in t2 unless more than 1
group by t1.Reg_No, t1.Student_Name
order by t1.Reg_No, t1.Student_Name

因此,如果(col1,col2,col3)的集合是(1,2,3),则t2最终为(1,2),其中最大值为2.

如果集合为(3,3,1),则t2最终为(3,3,1),最大值为3。

答案 2 :(得分:0)

这是一种不生成Row_Number

的方法
WITH cte 
     AS (SELECT reg_no, 
                student_name, 
                Max(v.col)OVER(partition BY reg_no, student_name) AS highest, 
                Min(v.col)OVER(partition BY reg_no, student_name) AS lowest, 
                col 
         FROM   Yourtable t 
                CROSS apply (VALUES (t.col1),(t.col2),(t.col3) ) v(col)) 
SELECT reg_no, 
       student_name, 
       lowest=Min(lowest), 
       Middle=Min(CASE WHEN col <> lowest AND col <> highest THEN col END), 
       highest=Max(highest) 
FROM   cte 
GROUP  BY reg_no, 
          student_name