Объединение трех таблиц с помощью MySQL


117

У меня есть три таблицы с названиями

**Student Table**
-------------
id    name
-------------
1     ali
2     ahmed
3     john
4     king

**Course Table**
-------------
id    name
-------------
1     physic
2     maths
3     computer
4     chemistry

**Bridge**
-------------
sid    cid
-------------
1     1
1     2
1     3
1     4
2     1
2     2
3     3
3     4
4     1
4     2

Теперь, чтобы показать имя студента с названием курса, который он изучал,

**Result**
---------------------------
Student        Course
---------------------------
ahmed         physic
ahmed         maths
ahmed         computer
ahmed         chemistry
ali           physic
ali           maths
john          computer
john          chemistry
king          physic
king          maths

Я строю следующий запрос

select s.name as Student, c.name as Course from student s, course c join bridge b on c.id = b.cid order by s.name

Но не возвращает требуемый результат ...

И что было бы для нормализованной формы, если я хочу найти, кто является менеджером над другими:

**employee**
-------------------
id        name
-------------------
1         ali
2         king
3         mak
4         sam
5         jon

**manage**
--------------
mid      eid
--------------
1         2
1         3
3         4
4         5

И хочет получить такой результат:

**result**
--------------------
Manager      Staff
--------------------
ali          king
ali          mak
mak          sam
sam          jon

в первом результате вы неправильно установили данные для ахмеда и али
NineCattoRules

Ответы:


150

Просто используйте:

select s.name "Student", c.name "Course"
from student s, bridge b, course c
where b.sid = s.sid and b.cid = c.cid 


1
Красиво и просто, но FWIW рассмотрим этот синтаксис в следующем блоге: sqlblog.org/2009/10/08/bad-habits-to-kick-using-old-style-joins, как указано в stackoverflow.com/a/13476050/ 199364
ToolmakerSteve

199

Используйте синтаксис ANSI, и вам будет намного понятнее, как вы объединяете таблицы:

SELECT s.name as Student, c.name as Course 
FROM student s
    INNER JOIN bridge b ON s.id = b.sid
    INNER JOIN course c ON b.cid  = c.id 
ORDER BY s.name 

9
@Muhammad: Наши ответы одинаковы, они отличаются только синтаксисом. Если вы не знаете ANSIсинтаксиса, стоит потратить время на его изучение. Это поможет вам избежать JOINподобных ошибок в будущем.
RedFilter

16

Для нормализации формы

select e1.name as 'Manager', e2.name as 'Staff'
from employee e1 
left join manage m on m.mid = e1.id
left join employee e2 on m.eid = e2.id

Имеет ли значение порядок в m.mid = e1.idи m.eid = e2.id?
Pathros

1
@Pathros Нет, порядок в этих выражениях не имеет значения.
ToolmakerSteve

4
SELECT *
FROM user u
JOIN user_clockits uc ON u.user_id=uc.user_id
JOIN clockits cl ON cl.clockits_id=uc.clockits_id
WHERE user_id = 158

Этот ответ очень похож на ответы, которые уже давались 5 лет назад. Что в вашем ответе, по вашему мнению, важно и чего нет в существующих ответах?
ToolmakerSteve

1
SELECT 
employees.id, 
CONCAT(employees.f_name," ",employees.l_name) AS   'Full Name', genders.gender_name AS 'Sex', 
depts.dept_name AS 'Team Name', 
pay_grades.pay_grade_name AS 'Band', 
designations.designation_name AS 'Role' 
FROM employees 
LEFT JOIN genders ON employees.gender_id = genders.id 
LEFT JOIN depts ON employees.dept_id = depts.id 
LEFT JOIN pay_grades ON employees.pay_grade_id = pay_grades.id 
LEFT JOIN designations ON employees.designation_id = designations.id 
ORDER BY employees.id;

Вы можете ПРИСОЕДИНЯТЬСЯ к нескольким ТАБЛИЦАм, как в примере выше.


Уже есть несколько ответов, полученных несколько лет назад, которые показывают «объединение нескольких таблиц». Что ваш ответ добавляет к обсуждению?
ToolmakerSteve

0

Запрос на объединение более двух таблиц:

SELECT ops.field_id, ops.option_id, ops.label
FROM engine4_user_fields_maps AS map 
JOIN engine4_user_fields_meta AS meta ON map.`child_id` = meta.field_id
JOIN engine4_user_fields_options AS ops ON map.child_id = ops.field_id 
WHERE map.option_id =39 AND meta.type LIKE 'outcomeresult' LIMIT 0 , 30

Уже есть несколько ответов, полученных несколько лет назад, которые показывают «объединение нескольких таблиц». Что ваш ответ добавляет к обсуждению?
ToolmakerSteve

0

Использовать это:

SELECT s.name AS Student, c.name AS Course 
FROM student s 
  LEFT JOIN (bridge b CROSS JOIN course c) 
    ON (s.id = b.sid AND b.cid = c.id);

1
Этот ответ не добавляет ничего нового к этому вопросу и использует странный (если не просто неправильный синтаксис, я был бы удивлен, если бы он был действителен даже в MySQL).
AeroX

Я не согласен с AeroX. Синтаксис соединения Ansi предназначен для устранения неоднозначности с синтаксисом старой запятой / where join. Я ищу, поддерживает ли MySql синтаксис соединения ansi.
Ларри Смит,

0

Не присоединяйся так. Это действительно плохая практика !!! Это снизит производительность при выборке больших объемов данных. Например, если в каждой таблице было 100 строк, сервер базы данных должен был выполнить выборку 100x100x100 = 1000000раз. Его нужно было принести на 1 millionвремя. Чтобы преодолеть эту проблему, присоединитесь к первым двум таблицам, которые могут получить результат с минимально возможным соответствием (это зависит от схемы вашей базы данных). Используйте этот результат в подзапросе, а затем присоедините его к третьей таблице и получите ее. Для самого первого соединения -> 100x100= 10000раз и предположим, что мы получили 5 совпадающих результатов. Затем мы присоединяемся к третьей таблице с результатом -> 5x100 = 500.Всего выборок = 10000+500 = 10200только раз. Таким образом, производительность выросла !!!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.