Joindre trois tables à l'aide de MySQL

117

J'ai trois tables nommées

**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

Maintenant, pour montrer le nom de l'étudiant avec le nom du cours qu'il avait étudié comme,

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

Je construis la requête suivante

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

Mais cela ne renvoie pas le résultat recherché ...

Et que serait la forme normalisée, si je veux trouver qui est le manager plutôt que les autres:

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

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

Et veut obtenir ce résultat:

**result**
--------------------
Manager      Staff
--------------------
ali          king
ali          mak
mak          sam
sam          jon
PHP Ferrari
la source
dans le premier résultat, vous avez mal défini les données pour ahmed et ali
NineCattoRules

Réponses:

199

Utilisez la syntaxe ANSI et la manière dont vous joignez les tables sera beaucoup plus claire:

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 
RedFilter
la source
9
@Muhammad: Nos réponses sont les mêmes, elles ne diffèrent que par la syntaxe. Si vous ne connaissez pas la ANSIsyntaxe, cela vaut la peine de l'apprendre. Cela vous aidera à éviter les JOINerreurs que vous avez commises à l'avenir.
RedFilter le
16

Pour normaliser la forme

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
PHP Ferrari
la source
L'ordre compte-t-il dans m.mid = e1.idet m.eid = e2.id?
Pathros
1
@Pathros Non, l'ordre n'a pas d'importance, dans ces expressions.
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
Ali Umair
la source
Cette réponse ressemble beaucoup aux réponses déjà données 5 ans plus tôt. Que pensez-vous de votre réponse importante et absente des réponses existantes?
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;

Vous pouvez REJOINDRE plusieurs TABLES comme cet exemple ci-dessus.

sameerNAT
la source
Il y a déjà plusieurs réponses, des années plus tôt, qui montrent «joindre plusieurs tables». Qu'est-ce que votre réponse ajoute à la discussion?
ToolmakerSteve
0

Requête pour joindre plus de deux tables:

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
Manish
la source
Il y a déjà plusieurs réponses, des années plus tôt, qui montrent «joindre plusieurs tables». Qu'est-ce que votre réponse ajoute à la discussion?
ToolmakerSteve
0

Utilisez ceci:

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);
user3477784
la source
1
Cette réponse n'ajoute rien de nouveau à cette question et utilise une syntaxe étrange (sinon tout à fait erronée, je serais surpris si cela était même valide dans MySQL).
AeroX
Je ne suis pas d'accord avec AeroX. La syntaxe de jointure Ansi est destinée à lever l'ambiguïté des problèmes avec la syntaxe de jointure virgule / where old school. Je cherche à voir si MySql prend en charge spécifiquement la syntaxe de jointure ansi.
Larry Smith
0

Ne vous joignez pas comme ça. C'est vraiment une très mauvaise pratique !!! Cela ralentira les performances de récupération avec des données massives. Par exemple, s'il y avait 100 lignes dans chaque table, le serveur de base de données doit récupérer les 100x100x100 = 1000000heures. Il fallait aller chercher des 1 millionfois. Pour surmonter ce problème, joignez les deux premières tables qui peuvent extraire le résultat d'une correspondance minimale possible (cela dépend de votre schéma de base de données). Utilisez ce résultat dans Subquery, puis joignez-le à la troisième table et récupérez-le. Pour la toute première jointure -> 100x100= 10000fois et supposons que nous obtenions 5 résultats correspondants. Et puis nous rejoignons la troisième table avec le résultat -> 5x100 = 500.Total fetch = 10000+500 = 10200times only. Et ainsi, la performance a augmenté !!!

Dracula Oppa
la source