2015-12-30 199 views
2

我有這樣的桌子;按升序排列選擇的列

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

關係數據庫不以這種方式工作,可以在SQL中實現,雖然,但我建議你要麼儲存過程中或最終輸出 –

+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值。

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.

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