我有一个简单的多学校管理系统,我正在努力获得教师总数和特定学校的学生总数。我的表格结构如下:
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'
答案 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。我没试过但它应该有用。