2016-02-22 51 views
0

该数据库在这里:http://sqlfiddle.com/#!9/bf0171两个表上的SQL查询;

我想找到“Prof.David”类的所有学生。然而,查询的结果是:

Select Student.name from Student, Teacher where Teacher.s_id =Student.id and Teacher.name="Prof. David"; 
+------+ 
| name | 
+------+ 
| Tom | 
| John | 
| Mary | 
| Tom | 
| John | 
| Mary | 
+------+ 

我想结果应该是“汤姆”,只有“约翰”。有什么问题?

回答

2

没有Student之间的连接标准Teacher你会得到一个Cartesian product(全部来自Student记录与所有记录Teacher相结合)。

你大概的意思是:

SELECT 
    Student.name 
FROM Student s 
JOIN Teacher t 
    ON t.s_id = s.id 
WHERE Teacher.name="Prof. David"; 

对于SQL的新学员,我会强烈建议使用JOINLEFT JOIN等,而不是暗中加入WHERE条款中明确使用。这将有助于减少您执行的意外笛卡尔产品的数量。

+0

这实际上与联接作品: “这里Teacher.s_id = Student.id和Teacher.name =” 教授。大卫“,它会正确返回”Tom“和”John“,而不使用”JOIN“ – user697911

+0

您可以隐式加入到WHERE子句中,但我不推荐它。如果需要执行左连接,会发生什么?你的WHERE标准有一个OR语句吗?有很多东西可能会出错,明确使用JOIN将有助于减少事故。 –

+0

@ user697911 - 为了讨论的缘故,这里是一个来自不同StackExchange的线程:http://程序员.stackexchange.com/q/78225 –

1

问题是您有两个表,并且您正在使用您的查询对这些表执行笛卡尔连接。因此,您的结果中会显示3x2 = 6行,其中每位教师都会显示所有3名学生的姓名。您必须根据架构中的外键关系以逻辑方式加入您的表。

例如:

Select A.field1, B.field2 from A join B on A.id = B.a_id

1

要看看是什么问题,试试这个:

Select Student.name, Teacher.name from Student, Teacher 

你会得到,每一个学生与每一位教师相结合,一个人是否有什么与其他与否的结果。需要补充的是检查,如果老师和学生相关的条件:

Select Student.name, Teacher.name from Student, Teacher where Teacher.s_id = Student.id 

一旦你有,你可以添加更多的条件,比如只列出一个给定的老师的学生。

Select Student.name from Student, Teacher where Teacher.s_id = Student.id and Teacher.name=... 
0

您需要在其中添加连接子句。我想你正试图选择在某个班上有特定教师的学生。因此,举例来说,如果你有:

table Student with columns: student_id, name 
table Teacher with columns: teacher_id, name 
table Class with columns: class_id, class_name, teacher_id 
table Class_Assignment with columns class_id, student_id 

然后将查询将是:

Select Student.name from Student, teacher, class_assignment 
    where Student.student_id = class_assignment.student_id 
    and Teacher.teacher_id = class_assignment.teacher_id 
    and Teacher.name="Prof. David";