检测MySQL DB记录之间的关系

时间:2013-11-25 15:22:43

标签: php mysql mysqli

假设我有3个数据库表:

  1. 教师,包括以下字段:
    • ID
    • 名称
  2. 科目,包括以下字段:
    • ID
    • 名称
  3. 教师 - 科目,包括以下字段:
    • teacher_id
    • subject_id
  4. 因此,一些教师有一个共同的主题。

    我已经考虑过用于查询的算法

      

    对于主题表中的每个记录:

         
        

    在teachers_subjects表中选择计数     如果count大于1
        在teacher_subjects中,获取teacher_id,其中subject_id是s。

      
         

    建立关系对。

    我希望获得如下输出:

    +----------+----------+---------------+
    | Teacher1 | Teacher2 | Relationships |
    +----------+----------+---------------+
    | John     | Larry    |            10 |
    | John     | Samantha |            12 |
    | Samantha | Larry    |             9 |
    | Ian      | Louis    |             3 |
    +----------+----------+---------------+
    

    如果我需要检索哪些科目建立了关系,我们需要得到类似的东西:

    +----+----------+----------+
    | id | teacher1 | teacher2 |
    +----+----------+----------+
    |  1 | John     | Larry    |
    |  2 | John     | Samantha |
    |  3 | Samantha | Larry    |
    |  4 | Ian      | Louis    |
    +----+----------+----------+
    

    等等:

    +-----+------------+
    | id  |  subject   |
    +-----+------------+
    | 1   | math       |
    | 1   | english    |
    | 1   | science    |
    | ... | ...        |
    | ... | ...        |
    | 4   | science    |
    | 4   | literature |
    | 4   | databases  |
    +-----+------------+
    

    以图形方式,我在通过网络浏览器查询的图表中表示这一点:

    Graph from DB query

    因此,当我悬停一条边时,它会显示关系信息。

    我将通过php编程接收查询结果,这样的查询或存储过程会产生这样的必需输出?

2 个答案:

答案 0 :(得分:3)

试试这个(您应该在SQLFiddle中加载一些示例数据以便更好地进行测试)

SELECT t1.`name` AS teacher1, t2.`name` AS teacher2, count(*)
FROM teachers AS t1
JOIN teachers AS t2
  ON t1.id > t2.id
JOIN teacher_subjects AS ts1
  ON ts1.teacher_id = t1.id
JOIN teacher_subjects AS ts2
  ON ts2.teacher_id = t2.id
    AND ts2.subject_id = ts1.subject_id
GROUP BY teacher1, teacher2
ORDER BY COUNT(*) DESC;

答案 1 :(得分:1)

这些是我对SQL的提议。

请记住,这些解决方案只是对以前的解决方案进行了一些修改。

第一张表

http://sqlfiddle.com/#!2/dc3f2/3

SELECT t1.name as 'Teacher1', t2.name as 'Teacher2', count(*) AS 'Relationships' 
FROM teachers t1 
JOIN teachers t2 ON t1.id > t2.id
JOIN teachers_subjects ts1 ON ts1.teacher_id = t1.id
JOIN teachers_subjects ts2 ON ts2.teacher_id = t2.id AND ts1.subject_id = ts2.subject_id
GROUP BY ts1.teacher_id, ts2.teacher_id;

第二张表

我认为它现在正在运作。

http://sqlfiddle.com/#!2/dc3f2/22

SELECT @rownum := @rownum + 1 as id, relations.Teacher1, relations.Teacher2
FROM (SELECT t1.name as 'Teacher1', t2.name as 'Teacher2'
FROM teachers t1 
JOIN teachers t2 ON t1.id > t2.id
JOIN teachers_subjects ts1 ON ts1.teacher_id = t1.id
JOIN teachers_subjects ts2 ON ts2.teacher_id = t2.id AND ts1.subject_id = ts2.subject_id
GROUP BY ts1.teacher_id, ts2.teacher_id) as relations,
(SELECT @rownum := 0) r;

第三张表

http://sqlfiddle.com/#!2/dc3f2/27

SELECT id, subject
FROM
(SELECT @rownum := @rownum + 1 as id, relations.Teacher1, relations.Teacher2, relations.id1, relations.id2
FROM (SELECT t1.name as 'Teacher1', t2.name as 'Teacher2', t1.id as 'id1', t2.id as 'id2'
FROM teachers t1 
JOIN teachers t2 ON t1.id > t2.id
JOIN teachers_subjects ts1 ON ts1.teacher_id = t1.id
JOIN teachers_subjects ts2 ON ts2.teacher_id = t2.id AND ts1.subject_id = ts2.subject_id
GROUP BY ts1.teacher_id, ts2.teacher_id) as relations,
(SELECT @rownum := 0) r) as rel
JOIN
(SELECT t1.id as 'id1', t2.id as 'id2', s.name as 'subject'
FROM teachers t1 
JOIN teachers t2 ON t1.id > t2.id
JOIN teachers_subjects ts1 ON ts1.teacher_id = t1.id
JOIN teachers_subjects ts2 ON ts2.teacher_id = t2.id AND ts1.subject_id = ts2.subject_id
JOIN subjects s ON ts1.subject_id = s.id) as rel_subjects
ON rel.id1 = rel_subjects.id1 AND rel.id2 = rel_subjects.id2
ORDER BY id

最后一件事。请记住,关系的伪键是非常多变的。这意味着如果您添加新行并删除一些,您将更改这些关系的ID。因此,不要出现任何错误,不能在数据库中的任何存储列中使用它们 - 只需在SELECT查询中使用它们。