2016-02-22 4 views
0

База данных находится здесь: http://sqlfiddle.com/#!9/bf0171SQL-поиск по двум таблицам;

Я хочу найти всех студентов в классе «Проф.Давид». Тем не менее, результат поиска является:

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, я настоятельно рекомендовал бы явно с помощью использования JOIN, LEFT JOIN и т.д. вместо неявного присоединения в пункте WHERE. Это поможет уменьшить количество случайных декартовых продуктов, которые вы выполняете.

+0

Это на самом деле работает с присоединиться: "где Teacher.s_id = Student.id и Teacher.name =" Prof , Дэвид », он возвращает« Tom »и« John »правильно, не используя« JOIN ». – user697911

+0

Вы можете присоединиться неявно в предложении WHERE, но я не рекомендую его. Что произойдет, если вам нужно сделать левое соединение? ваш критерий WHERE имеет инструкцию OR? Существует множество вещей, которые могут пойти не так, и явное использование JOIN поможет уменьшить количество несчастных случаев. –

+0

@ user697911 - Для обсуждения здесь приведен поток из другого StackExchange по проблеме: http: // programers.stackexchange.com/q/78225 –

1

Проблема в том, что у вас есть две таблицы, и вы выполняете декартовое соединение в этих таблицах с вашим запросом. Таким образом, вы получаете 3x2 = 6 строк в результатах, где для каждого преподавателя вы показываете имена всех трех учеников. Вы должны подключиться к своим таблицам логически, основываясь на отношениях внешних ключей в вашей схеме.

Например:

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"; 
Смежные вопросы