2017-01-16 111 views
1

我有以下情況(我演示的示例是在虛擬域上,因爲NDA原因等)。子查詢解決方法中可能的「限制n/select top n」限制

我有機會到生產的DB下面的形狀保持學生數據:

Student_ID Course_Name Total_Average_Grade 
1   Maths  19,1 
1   Physics  0 
1   Biology  0 
2   Physics  18,5 
2   Chemistry 0 
3   Maths  19,4 
3   Literature 0 
3   Physics  0 

我想要檢索說,10名學生最高的總平均成績,併爲那些10檢索整個列表他們採取的課程。我想按月運行此查詢。

例如,在上表中,如果我想選擇頂部2名學生,輸出將是:

Student_ID Course_Name Total_Average_Grade 
3   Maths  19,4 
3   Physics  0 
3   Biology  0 
1   Maths  19,1 
1   Literature 0 
1   Physics  0 

請注意,我沒有權利來創建此任視圖或存儲過程數據庫,這將是一種簡單的方法來克服無法在(select n/limit n)選擇上執行子查詢的限制(例如,我將能夠自動創建一個我將用於加入的月度視圖與平原選擇前10平均等)。

這個任務有沒有優雅的解決方案?

爲了記錄,我使用Sybase 15.4作爲客戶端來訪問Sybase IQ生產數據庫。

+0

添加樣品輸出爲輸入表 –

+0

校驗輸出PLZ。學生1獲得19,4?但在輸入表中它的19,1? –

+0

固定(錯誤由於複製粘貼:)) – rpd

回答

1

我想你可以使用這樣的查詢:

select * 
from (
    select *, 
     row_number() over (partition by Course_Name order by Total_Average_Grade desc) as rn 
    from yourTable) t 
where t < 11; 
+0

這兩個工作,但第一個解決方案更優雅。我對分析SQL函數和邏輯有點新鮮,在使用分析函數時,這個任務和類似似乎比想象的要容易得多。 – rpd

1

檢查下面的查詢其成功運行的SQL Server。

 DECLARE @student TABLE(
       Student_ID INT,   
       Course_Name VARCHAR(100), 
       Total_Average_Grade VARCHAR(100) 
     ) 

     INSERT INTO @student 
     select 1, 'Maths '  ,'19.1' union 
     select 1, 'Physics'  ,'0'union 
     select 1, 'Biology'  ,'0'union 
     select 2, 'Physics'  ,'18.5'union 
     select 2, 'Chemistry' ,'0'union 
     select 3, 'Maths'  ,'19.4'union 
     select 3, 'Literature' ,'0'union 
     select 3, 'Physics'  ,'0' 


     ;WITH ValList AS(
       SELECT Student_ID,Course_Name, Case when Total_Average_Grade like '%,%' then 

         CAST(LEFT(Total_Average_Grade,PATINDEX('%,%', Total_Average_Grade) - 1) AS float) 
         else Total_Average_Grade end as 
         Total_Average_Grade, 
         RIGHT(Total_Average_Grade,LEN(Total_Average_Grade) - PATINDEX('%,%', Total_Average_Grade)) Remainder 

       FROM @student 
       UNION ALL 
       SELECT Student_ID,Course_Name, 
         CAST(LEFT(Remainder,CASE WHEN PATINDEX('%,%', Remainder) = 0 THEN LEN(Remainder) ELSE PATINDEX('%,%', Remainder) - 1 END) AS float) Total_Average_Grade, 
         RIGHT(Remainder,CASE WHEN PATINDEX('%,%', Remainder) = 0 THEN 0 ELSE LEN(Remainder) - PATINDEX('%,%', Remainder) END) Remainder 
       FROM ValList 
       WHERE LEN(Remainder) > 0 

     ) 


     select SS.* from @student SS 
     join 
     (
     SELECT top 2 v.Student_ID -- use TOP 10 for 10 records 
     --,s.Course_Name,s.Total_Average_Grade,SUM(v.Total_Average_Grade) as Avg, 
     ,row_number() over(order by SUM(v.Total_Average_Grade) desc) rnk 
     FROM ValList V 
     join @student S on s.Student_ID=V.Student_ID and s.Course_Name=V.Course_Name 
     GROUP BY v.Student_ID 
     )AA on AA.Student_ID=SS.Student_ID 
     order by rnk asc,Total_Average_Grade desc 

輸出:

enter image description here