1

私はmySQLでこのシナリオをどのように進めるかを理解しようとしています -

3 つのテーブルがあります。テーブルt_student, t_teacher, t_result の構造 (基本的に各テーブルの列) は次のとおりです。

t_student:
s_id, s_name, s1, s2, s3

ここで、s_id は主キー、s_name は生徒の名前、(s1、s2、s3) は数学、物理、化学などの科目です。

t_teacher:
t_id, t_name, s1, s2, s3

ここで、t_id は主キー、t_name は教師の名前、(s1,s2,s3) は数学、物理学、化学などの科目です。

t_result:
r_id, s_name, t_name, count

ここで、r_id は主キー、s_name は (student テーブルからの) 生徒の名前、t_name は (teach テーブルからの) 教師の名前、count は count を返します (これについては後で詳しく説明します)。

今、私がやりたいことは以下の通りです:

生徒と教師のテーブルには任意の数のレコードが存在する可能性がありますが、現時点では結果テーブルには何もありません。ここで、mySQL を使用して、学生テーブルの内容をスキャンしたいと思います。このテーブルの各レコードについて、ピックアップしたいと思います。

s1 の値を教師テーブル s2 の (s1,s2,s3) 列と比較し、値を教師テーブル s3 の (s1,s2,s3) 列と比較し、値を (s1,s2,s3) と比較します。教師テーブルの列

一致する値の数を取得し、count に格納します。

より明確にするために、生徒テーブルの最初のレコードの場合、s1、s2、および s3 が「phy」、「chem」、および「maths」であり、教師テーブルの最初のレコードが「maths」、「phy」、「computer」である場合"、この場合、student.s1 は teacher.s2 と一致するため、count は 1 になります。次に、student.s2 は teacher テーブルの s1、s2、s3 と一致しますが、一致は 0 であるため、count は 1 のままです。再び、student.s3 は、teach テーブルの s1、s2、s3 と照合されます。今回は、teacher.s1 と一致するため、count は 2 に増加します。したがって、student テーブルの最初のレコードと、teach テーブルの最初のレコードの比較の最後に、私はcount = 2を取得します。ここで、生徒の名前、教師の名前、および取得したカウントを含む行を結果テーブルに挿入します。

基本的に、学生テーブルの各行について、学生テーブルと教師テーブルの間で一致する s1、s2、s3 の数を取得し、これを結果テーブルに入れたいと考えています。

私はmysqlの基本的な操作しか知りません-選択、挿入、削除など..そのような操作には、plsqlやストアドプロシージャなど、それ以上のものが必要だと思いますか?

参考までに、私は phpmyadmin を使用しており、テーブルはそこに保存されています。テーブルから結果を取得し、これらのクエリを実行するには、php を使用します。

そのためのアプローチを教えてください。

ありがとう!

4

4 に答える 4

1

テーブルを次のように変更する必要があります

t_student:
s_id, s_name, s_s

t_teacher:
t_id, t_name, t_s

s1、s2、s3を分割して行を分割します。次に、t_studentとt_teacherの間で単純な結合を行うことができます。

于 2012-10-13T19:05:59.683 に答える
1

データベースの設計にはいくつかの作業が必要です。データを正規化することから始めて、繰り返される科目の列を教師と生徒のテーブルから移動します。これを行うには、次のテーブルを作成します。

CREATE TABLE t_subjects ( subject_id INT, name VARCHAR(30) );
CREATE TABLE t_teacher_subjects ( teach_id INT, subject_id INT);
CREATE TABLE t_student_subjects ( student_id INT, subject_id INT);

Teacher と Student から s1、s2、s3 列を削除すると、次のような単一のクエリで結果テーブルにデータを入力できるようになります (auto_increment 主キーがある場合)。

insert into t_result (s_name, t_name, count) 
select t_teacher.t_name, t_student.s_name, count(*) as c from
t_teacher_subjects 
    inner join t_student_subjects on t_teacher_subjects.subject_id = t_student_subjects.subject_id
    inner join t_teacher on t_teacher_subjects.teach_id = t_teacher.t_id
    inner join t_student on t_student_subjects.student_id = t_student.s_id
group by t_teacher.t_name, t_student.s_name;
于 2012-10-13T18:57:47.573 に答える
0

実際、これを解決するために手続き型コードは必要ありません。このアプローチは「正規化」と呼ばれます。教師の科目を表すには複数のテーブルが必要です。そのため、s1、s2、s3の値は、教師テーブルと外部キーの関係にある別のテーブルの1つの列に移動します。他の関係についても同じです。(そのため、そもそも「リレーショナルデータベース」という用語が使われています。)

関連する議論はここにあります:DB設計:第一正規形と繰り返しグループ

編集

本番の問題というよりは課題のように見えます:)。とにかく、スキーマではなくクエリで正規化するために、複雑な純粋なSQLアプローチを試すことができます。奇妙ですが不可能ではありません。

これがトリックの本質です。これをサブクエリとして使用して、データの正規化された表現を取得します。

select s_id, s_name, s1 s from t_student
union
select s_id, s_name, s2 s from t_student
union
select s_id, s_name, s3 s from t_student
于 2012-10-13T18:37:07.720 に答える
0

良い。この挑戦に感謝します。いい頭の体操です:)。

クエリは次のとおりです。それを挿入に変換するだけです:

select s_name, t_name, count(*) cnt from
(
select s.s_name, s.s s_s, t.t_name, t.s t_s from
(
select s_id, s_name, s1 s from t_student
union
select s_id, s_name, s2 s from t_student
union
select s_id, s_name, s3 s from t_student
) s
inner join
(
select t_id, t_name, s1 s from t_teacher
union
select t_id, t_name, s2 s from t_teacher
union
select t_id, t_name, s3 s from t_teacher
) t
on t.s = s.s
) m
group by s_name, t_name
;

編集:実際の実行:

mysql> select * from t_student;
+------+--------+------+------+------+
| s_id | s_name | s1   | s2   | s3   |
+------+--------+------+------+------+
|    1 | st1    | qqq  | www  | eee  |
|    2 | st2    | 111  | 222  | 333  |
|    3 | st3    | zzz  | xxx  | ccc  |
+------+--------+------+------+------+
3 rows in set (0.00 sec)

mysql> select * from t_teacher;
+------+--------+------+------+------+
| t_id | t_name | s1   | s2   | s3   |
+------+--------+------+------+------+
|    1 | te1    | qqq  | www  | eee  |
|    2 | te2    | 111  | 222  | nnn  |
|    3 | te3    | zzz  | nnn  | nnn  |
+------+--------+------+------+------+
3 rows in set (0.00 sec)

mysql> select s_name, t_name, count(*) cnt from
    -> (
    -> select s.s_name, s.s s_s, t.t_name, t.s t_s from
    -> (
    -> select s_id, s_name, s1 s from t_student
    -> union
    -> select s_id, s_name, s2 s from t_student
    -> union
    -> select s_id, s_name, s3 s from t_student
    -> ) s
    -> inner join
    -> (
    -> select t_id, t_name, s1 s from t_teacher
    -> union
    -> select t_id, t_name, s2 s from t_teacher
    -> union
    -> select t_id, t_name, s3 s from t_teacher
    -> ) t
    -> on t.s = s.s
    -> ) m
    -> group by s_name, t_name
    -> ;

+--------+--------+-----+
| s_name | t_name | cnt |
+--------+--------+-----+
| st1    | te1    |   3 |
| st2    | te2    |   2 |
| st3    | te3    |   1 |
+--------+--------+-----+
3 rows in set (0.00 sec)
于 2012-10-13T20:36:45.743 に答える