我有一张这样的桌子;
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
答案 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