MYSQL加入三个表

时间:2017-06-22 13:21:04

标签: php mysql left-join

我有一个简单的多学校管理系统,我正在努力获得教师总数和特定学校的学生总数。我的表格结构如下:

        teachers
--------------------------
id | schoolid | Name | etc...
--------------------------
1  |    1     | Bob  |
2  |    1     | Sarah|
3  |    2     | John |


        students
--------------------------
id | schoolid | Name | etc... 
--------------------------
1  |    1     | Jack |
2  |    1     | David|
3  |    2     | Adam |

        schools
--------------------------
id |      Name       | etc...
---------------------------
 1 | River Park High |
 2 | Stirling High   |

我可以通过以下查询统计所有教师:

SELECT COUNT(a.id) AS `totalteachers` 
FROM teachers a 
LEFT JOIN schools b ON a.schoolid = b.id WHERE b.id = '1'

同样我可以使用以下查询来计算教师数量:

SELECT COUNT(a.id) AS `totalstudents` 
FROM students a 
LEFT JOIN schools b ON a.schoolid = b.id WHERE b.id = '1'

然而,我正在努力尝试将这两个查询组合起来得到一个像这样的简单结果:

totalstudents | totalteachers
--------------------------------
       2      |      2

我尝试了以下内容:

SELECT COUNT(a.id) as `totalteachers`, COUNT(c.id) as `totalstudents` 
FROM teachers a 
LEFT JOIN schools b ON a.schoolid = b.id 
LEFT JOIN students c ON c.schoolid=b.id WHERE b.id = '5'

3 个答案:

答案 0 :(得分:3)

你可以做这样的事情

SELECT 
  id, name, s.total AS totalstudents, t.total AS totalteachers
FROM schools
  JOIN (SELECT schoolid, COUNT(id) AS total FROM teachers GROUP BY schoolid)
    AS t ON t.schoolid = id        
  JOIN (SELECT schoolid, COUNT(id) AS total FROM students GROUP BY schoolid)
    AS s ON s.schoolid = id

然后你可以添加where id = 2或其他任何限制学校。

答案 1 :(得分:2)

多个左连接的问题是它为每个学生为每个学生生成额外的记录;人为地夸大你的计数

有四种方法可以解决这个问题:(最好的imo就是Andrew Bone所做的)

只需在没有连接的情况下选择内联,这样计数就不会膨胀。 (在我看来最可取,因为它易于维护)

SELECT (SELECT COUNT(a.id) AS `totalteachers` 
        FROM teachers a 
        WHERE A.SchoolID = '1') as TotalTeachers
     , (SELECT COUNT(a.id) AS `totalstudents` 
        FROM students a 
        WHERE a.SchoolID = '1') as TotalStudents

使用子查询在连接之前首先获取计数,然后加入。由于count始终为1,因此交叉连接起作用。

SELECT totalTeachers, totalStudents 
FROM (SELECT COUNT(a.id) AS `totalteachers` 
      FROM teachers a 
      LEFT JOIN schools b 
        ON a.schoolid = b.id 
      WHERE b.id = '1')
CROSS JOIN (SELECT COUNT(a.id) AS `totalstudents` 
            FROM students a 
            LEFT JOIN schools b ON a.schoolid = b.id 
            WHERE b.id = '1')

在计数中使用不同的关键词,以免复制计数并消除人为膨胀(在我看来最不可取,因为这隐藏了人为计数的增加)

SELECT COUNT(distinct a.id) as `totalteachers`, COUNT(distinct c.id) as `totalstudents` 
FROM teachers a 
LEFT JOIN schools b ON a.schoolid = b.id 
LEFT JOIN students c ON c.schoolid=b.id WHERE b.id = '5'

另一种方法是使用窗口函数,但这些在mySQL中不可用。

答案 2 :(得分:0)

SELECT COUNT(t.id) AS TotalTeachers, COUNT(st.id) AS TotalStudents
FROM schools s
INNER JOIN teachers t
ON s.id = t.schoolid
INNER JOIN students st
ON s.id = st.schoolid

试试这个SQL。我没试过但它应该有用。