1

我试图弄清楚如何在 mySQL 中处理这种情况 -

共有三个表 - 表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 是学生姓名(来自学生表),t_name 是教师姓名(来自教师表)并且 count 给出计数(稍后会详细介绍)

现在,我想做的是如下:

学生和教师表中可能有任意数量的记录,而结果表中目前没有。现在,使用 mySQL 我想扫描学生表的内容,并且对于该表中的每条记录,我想拾取:

s1,然后将值与教师表 s2 中的 (s1,s2,s3) 列进行比较,然后将值与教师表 s3 中的 (s1,s2,s3) 列进行比较,然后将值与 (s1,s2,s3) 进行比较教师表中的列

并获取匹配值的数量并存储在计数中。

为了更清楚,如果学生表中的第一条记录,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 与教师表中的 s1,s2,s3 匹配,这次与教师表中的 s1 匹配,因此计数增加为 2。所以在比较学生表中的第一条记录与教师表的第一条记录时,我得到计数​​= 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);

从教师和学生中删除 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

出色地。感谢您的挑战。一个很好的心理锻炼:)。

这是查询;只需将其转换为插入:

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 回答
0

实际上,您不需要任何程序代码来解决这个问题。该方法称为“标准化”。您需要多个表来表示教师的科目,以便 s1、s2、s3 值转到单独表中的单个列,该表与教师表具有外键关系。其他关系也一样。(这就是为什么首先使用术语“关系数据库”。)

相关讨论在这里:DB Design: 1st Normal Form and Repeating Groups

编辑

看起来像是一个任务而不是一个生产问题:)。无论如何,您仍然可以尝试使用复杂的纯 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 回答