Приєднання до трьох таблиць за допомогою 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

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

Відповіді:


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
інструментів,

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
@ Мухаммед: Наші відповіді однакові, вони відрізняються лише синтаксисом. Якщо ви не знаєте 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?
Патрос

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 призначений для розмежування проблем зі старою шкільною комою / де приєднується синтаксис. Я дивлюсь, чи підтримує MySql підтримку ансі приєднатись до синтаксису.
Ларрі Сміт

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.