0

次のようなテーブルがあります

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

同じ科目セットを持つ学生をグループ化する必要があります。同じ科目セットを持つ学生に一意のグループ ID を与えるだけで済みます。

したがって、ここで学生ID(1)と(4)はグループID = 1となります

学生 ID 2 - グループ ID = 2 (他の誰もサブ 1 とサブ 2 しか持っていません)

学生 ID 3 - グループ ID = 3

結果は次のようになります

 studentid groupid
     1        1
     4        1
     2        2
     3        3

FORXML を使用して学生のすべての科目を 1 つの列にグループ化し、その列でグループ化を使用してランクを関連付ける sqlquery を作成しました。これを行うより良い方法はありますか

4

2 に答える 2

1

ここに 1 つのアプローチがあります。

各学生について、同じコースのセットを持つ他のすべての学生を見つけます。これを行うには、次の規則を使用します。2 人の学生が同じコースを持っている場合、(1) それぞれのコース数が同じである。(2) 共通するコースの数は、コースの数と同じです。

この実装では、ランキング関数を使用してコースの数を見つけ、結合/グループ化を使用して 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   

dense_rank「穴」のないグループ ID が必要な場合は、グループ ID の割り当てに使用する外部クエリをラップできます。

于 2012-11-19T15:54:02.107 に答える
0

これを処理する 1 つの方法は、サブジェクトのビットマスクを作成することです。最初に、各被験者に個別の任意の 2 の累乗を割り当てます。

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
于 2012-11-19T16:14:16.060 に答える