遇到查询问题,特别是连接问题
Having trouble a query and specifically with joins
下面的代码完全错误,根本不起作用。我基本上是想浏览我的 tables 并编制一份 DeptName 列表和一个部门有超过 40 名学生的部门的总学生人数。
我对一般的联接感到困惑,如果有人可以解释并说明我哪里出错了。我确定还有其他问题,所以对他们的任何帮助都会有所帮助
所以基本上一个系连接到一个模块,一个学生注册到一个模块。学生不能在其系外学习模块。所以每个学生应该有一个连接到一个部门的模块
其他 tables 中的所有 ID 字段都是外键,您可以猜到,更改 tables 不是我想在这里做的我只想做这个查询这代表
相关 tables 列
Table部门DeptID
,DeptName
,Faculty
,Address
Table 模块 ModuleID
, ModuleName
, DeptID
, Programme
Table 学生 StudentID
,StudentName
,DoB
,Address
,StudyType
,`
Table 入学人数 EID
,StudentID
,ModuleID
,Semester
,Year
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students' FROM Department LEFT JOIN Module ON Department.DeptID= Module.DeptID LEFT JOIN Enrolment ON Module.ModuleID= Enrolment.StudentID LEFT JOIN Student.StudentID
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
我没有把每个 table 都包括在这里,因为有很多。
但是除非我完全弄错了,否则您不需要访问员工 table 中的 ModuleID 以获取他们教授的模块或与此完全不相关的内容。因为里面没有学生或部门的详细信息。
如果是这种情况,我会很快解决它。
您需要使用 inner join
而不是 left join
,因为您只需要从这三个表中 select 相关行。
Groupy by
和 having
子句似乎没问题。由于您需要学生人数超过 40 人的院系,而不是 >=
,请使用 COUNT(e.StudentID)>40
SELECT d.DeptName, COUNT(e.StudentID) AS 'No of Students' FROM Department d INNER JOIN Module m ON d.DeptID= m.DeptID inner JOIN Enrolment e ON m.ModuleID= e.StudentID LEFT JOIN Student.StudentID
GROUP BY(d.DeptName)
HAVING COUNT(e.StudentID)>40
所以你的连接子句在你写的时候 students
有点不确定,大概这些都应该是内部连接。
我已经使用别名重新格式化了您的查询,以使其更易于阅读。
由于您计算的是每个 DeptName 的行数,因此您可以简单地执行 count(*)
,同样在您的 having
中,您只计算大于 40 的行数。如果没有看到您的模式和数据,就不可能知道您是否可能有重复的学生,如果是这种情况并且您希望不同的学生计数可以修改为 count(distinct s.studentId)
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Enrolment e on e.StudentId=m.ModuleId
join Students s on s.StudentId=e.studentId
group by(d.DeptName)
having Count(*)>40
此外,查看您的加入条件,注册 table 是否相关?
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Students s on s.StudentId=m.moduleId
group by(d.DeptName)
having Count(*)>40
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students'
FROM Department
LEFT JOIN Module
ON Department.DeptID= Module.DeptID
LEFT JOIN Enrolment
-- problem #1:
ON Module.ModuleID= Enrolment.StudentID
-- problem #2:
LEFT JOIN Student.StudentID
-- problem #3:
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
- 您加入这两个 table 时使用了错误的字段。通常当建模正确完成时,您应该使用
USING
而不是 ON
来连接
- 任何
JOIN
运算符的右侧必须是 table,而不是列。
- 您必须按 select 子句中不属于
COUNT
之类的聚合函数的每一列进行分组。我建议您 select DeptID 而不是名称,然后使用此查询的结果在后续 select. 中查找名称
注意:以下代码未经测试。
WITH bigDepts AS (
SELECT DeptId, COUNT(StudentID) AS StudentCount
FROM Department
JOIN Module
USING ( DeptID )
JOIN Enrolment
USING ( ModuleID )
JOIN Student
USING ( StudentID )
GROUP BY DeptID
HAVING COUNT(StudentID)>=40
)
SELECT DeptID, DeptName, StudentCount
FROM Department
JOIN bigDepts
USING ( DeptID )
下面的代码完全错误,根本不起作用。我基本上是想浏览我的 tables 并编制一份 DeptName 列表和一个部门有超过 40 名学生的部门的总学生人数。
我对一般的联接感到困惑,如果有人可以解释并说明我哪里出错了。我确定还有其他问题,所以对他们的任何帮助都会有所帮助
所以基本上一个系连接到一个模块,一个学生注册到一个模块。学生不能在其系外学习模块。所以每个学生应该有一个连接到一个部门的模块
其他 tables 中的所有 ID 字段都是外键,您可以猜到,更改 tables 不是我想在这里做的我只想做这个查询这代表
相关 tables 列
Table部门DeptID
,DeptName
,Faculty
,Address
Table 模块 ModuleID
, ModuleName
, DeptID
, Programme
Table 学生 StudentID
,StudentName
,DoB
,Address
,StudyType
,`
Table 入学人数 EID
,StudentID
,ModuleID
,Semester
,Year
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students' FROM Department LEFT JOIN Module ON Department.DeptID= Module.DeptID LEFT JOIN Enrolment ON Module.ModuleID= Enrolment.StudentID LEFT JOIN Student.StudentID
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
我没有把每个 table 都包括在这里,因为有很多。
但是除非我完全弄错了,否则您不需要访问员工 table 中的 ModuleID 以获取他们教授的模块或与此完全不相关的内容。因为里面没有学生或部门的详细信息。
如果是这种情况,我会很快解决它。
您需要使用 inner join
而不是 left join
,因为您只需要从这三个表中 select 相关行。
Groupy by
和 having
子句似乎没问题。由于您需要学生人数超过 40 人的院系,而不是 >=
,请使用 COUNT(e.StudentID)>40
SELECT d.DeptName, COUNT(e.StudentID) AS 'No of Students' FROM Department d INNER JOIN Module m ON d.DeptID= m.DeptID inner JOIN Enrolment e ON m.ModuleID= e.StudentID LEFT JOIN Student.StudentID
GROUP BY(d.DeptName)
HAVING COUNT(e.StudentID)>40
所以你的连接子句在你写的时候 students
有点不确定,大概这些都应该是内部连接。
我已经使用别名重新格式化了您的查询,以使其更易于阅读。
由于您计算的是每个 DeptName 的行数,因此您可以简单地执行 count(*)
,同样在您的 having
中,您只计算大于 40 的行数。如果没有看到您的模式和数据,就不可能知道您是否可能有重复的学生,如果是这种情况并且您希望不同的学生计数可以修改为 count(distinct s.studentId)
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Enrolment e on e.StudentId=m.ModuleId
join Students s on s.StudentId=e.studentId
group by(d.DeptName)
having Count(*)>40
此外,查看您的加入条件,注册 table 是否相关?
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Students s on s.StudentId=m.moduleId
group by(d.DeptName)
having Count(*)>40
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students'
FROM Department
LEFT JOIN Module
ON Department.DeptID= Module.DeptID
LEFT JOIN Enrolment
-- problem #1:
ON Module.ModuleID= Enrolment.StudentID
-- problem #2:
LEFT JOIN Student.StudentID
-- problem #3:
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
- 您加入这两个 table 时使用了错误的字段。通常当建模正确完成时,您应该使用
USING
而不是ON
来连接 - 任何
JOIN
运算符的右侧必须是 table,而不是列。 - 您必须按 select 子句中不属于
COUNT
之类的聚合函数的每一列进行分组。我建议您 select DeptID 而不是名称,然后使用此查询的结果在后续 select. 中查找名称
注意:以下代码未经测试。
WITH bigDepts AS (
SELECT DeptId, COUNT(StudentID) AS StudentCount
FROM Department
JOIN Module
USING ( DeptID )
JOIN Enrolment
USING ( ModuleID )
JOIN Student
USING ( StudentID )
GROUP BY DeptID
HAVING COUNT(StudentID)>=40
)
SELECT DeptID, DeptName, StudentCount
FROM Department
JOIN bigDepts
USING ( DeptID )