0

申し訳ありませんが、タイトルは少し誤解を招くものです。次のテーブルがあるとします

-- user_tests テーブル
名前 | タイプ
------------------------|----------------
ID | int(11)
ユーザー ID | int(11)
test_schedule_id | int(11)
device_user_test_id | varchar(255)
所要時間 | int(11)
合計マーク | int(11)
合計_質問 | int(11)
試行回数 | int(11)
created_at | 日付時刻
updated_at | 日付時刻
-- user_test_questions テーブル
名前 | タイプ
--------------|-------------
ID | 整数
user_test_id | 整数
所要時間 | 整数
mark_obtained | 整数
質問ID | 整数
正しいです | 列挙
test_section_id | 整数
created_at | 日付時刻
updated_at | 日付時刻

表のデータは、 でuser_tests識別される特定の試験を受けた学生のリストですtest_schedule_id。それぞれtest_schedule_id、 には 1 つ以上の がありtest_section_idます。

次の条件で学生のランクを計算しようとしています。

  1. 学生の total_marks に基づいてランクを取得するtest_schedule_id
  2. 前のケースのランクが同じ場合、ランクを取得test_section_id= 1
  3. 前のケースのランクが同じ場合、ランクを取得test_section_id= 2
  4. 前のケースのランクが同じ場合、ランクを取得test_section_id= 3
  5. 前のケースのランクが同じ場合、users テーブルにあるユーザーの生年月日のランクを取得します

Rails (または任意のフレームワーク) で簡単に実行できますが、それを避けて、Viewまたはを使用して SQL で解決したいと考えていますStored Procedure

ランクを個別に計算する方法はわかりましたが、これらの条件を組み合わせるのに苦労しています。これを行う方法はありますか?MS SQL Server の Rank() 関数が不足していると思います。

ありがとうございました

編集:テーブル内またはテーブル内のいずれかtotal_marksに基づいてランク付けします。user_testsSUM(marks_obtained)user_test_questions

4

1 に答える 1

1

mysql にその仕事をさせるのは良い考えです - すべての結合とソートの種類のものです。

私は次のようなものに行きます:

SELECT u.id AS uid, 
  SUM( utq.marks_obtained ) AS total_marks,
  SUM( (utq.test_section_id = 1)*utq.marks_obtained ) AS section1_marks,
  SUM( (utq.test_section_id = 2)*utq.marks_obtained ) AS section2_marks,
  SUM( (utq.test_section_id = 3)*utq.marks_obtained ) AS section3_marks,
  u.birthdate
FROM user_test_questions utq
JOIN user_tests ut ON ut.id = utq.user_test_id
JOIN users u ON u.id = ut.user_id
WHERE ut.test_schedule_id = 1
GROUP BY utq.user_test_id, u.id, u.birthdate
ORDER BY total_marks DESC, section1_marks DESC, section2_marks DESC, section3_marks DESC, u.birthdate

各セクションのマークをカウントする秘訣は、marks_obtained にブール値 (test_section_id=1) を乗算することです。これは、test_section_id = 1 の行では 1 になり、他のセクションでは 0 になります。

GROUP BY には、SQL 標準に準拠する 3 つの列が表示されますが、utq.user_test_id だけを表示することもできます。これは、他の列が各グループ内で同じ値を持つためです。

test_schedule_id の非常に選択的な条件 (明らかにインデックスを作成する必要があります) と、各テストに参加する学生の数が少ない (せいぜい数百人) ため、すべての並べ替えが非常に小さな一時テーブルで行われるため、このクエリは即座に実行されます。

于 2013-06-14T06:56:30.073 に答える