2012-11-19 84 views
0

我有一個表如下SQL查詢來發現分組

studentID Subject 
    1  Sub1 
    2  Sub1 
    3  Sub1 
    4  Sub1 
    1  Sub2 
    2  Sub2 
    4  Sub2 
    1  Sub3 
    3  Sub3 
    4  Sub3 

我需要組誰擁有同一套Subjects.Just的學生需要一個提供一個獨特的組ID與學生同一套科目。

所以這裏的學生證(1)和(4)將得到要說組ID = 1

學生證2 - 組ID = 2(別人只子1子2)

學生ID 3 - 基團ID = 3

的結果應該是像

studentid groupid 
    1  1 
    4  1 
    2  2 
    3  3 

我已經寫它使用FORXML到組學生的所有受試者爲單個列,然後使用一個組b SQLQuery對在那一列上,然後將一個等級與他們聯繫起來。有沒有更好的方法來做到這一點

+0

很好的問題,這是不容易的SQL。使用'for xml'創建一個組描述似乎是解決這個問題的巧妙方法。 – Andomar

+0

我認爲這是一個很好的方式來解決這個連接的分組。儘管如此,你必須檢查你是否有連接字符串中的主題的正確順序 –

回答

1

這是一種方法。

對於每個學生,找到所有其他具有相同課程集的其他學生。您可以通過使用以下規則來做到這一點。兩名學生在以下情況下有相同的課程:(1)每門課程數相同; (2)他們的課程數量與課程數量相同。

該實現使用排名函數來查找課程數量和加入/分組數,通過統計兩個不同學生的共同數量。

之後,組ID就是此表中對中的最小學生ID。

select s1.StudentId, MIN(SameAsStudentId) as groupid 
from (select s1.StudentId as StudentId, s2.StudentId as SameAsStudentId 
     from (select ss.*, COUNT(*) over (studentId) as NumSubjects 
      from ss 
      ) s1 join 
      (select ss.*, COUNT(*) over (studentId) as NumSubjects 
      from ss 
      ) s2 
      where s1.Subject = s2.Subject 
     group by s1.StudentId, s2.StudentId 
     having s1.NumSubjects = s2.NumSubjects and 
      COUNT(*) = s1.NumSubjects 
    ) t 
group by StudentId 

如果你想要一個沒有「洞」的groupid,你可以用一個使用dense_rank分配組ID的外部查詢。

0

處理此問題的一種方法是爲主體創建一個位掩碼。首先分配兩個不同的,任意的權力,每名受試者:

Subject Value 
Sub1   1 
Sub2   2 
Sub3   4 

現在你可以總結每個學生的主體性的價值。每個科目組合都有獨特的價值。有一個警告,如果主題的數量太大,你可能會得到一個數字溢出。

你甚至可以做到這一點在一個查詢:

Select StudentID, sum(Subject_Value) 
from Student_Subjects ss join 
    (select distinct subject, 
         power(2,dense_rank() 
           over (order by subject)-1) as Subject_Value 
     from Student_Subjects) sv 
    on ss.subject = sv.subject 
group by StudentID