使用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

在第一个结果中,您错误地为ahmed和ali设置了数据
NineCattoRules

Answers:



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 2010年

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不,在这些表达式中顺序无关紧要。
制造商

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

这个答案看起来与五年前已经给出的答案非常相似。您认为答案很重要,而现有答案中却没有?
制造商史蒂夫

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;

您可以像上面的示例一样加入多个表。


从几年前开始,已经有多个答案显示“联接多个表”。您的回答对讨论有什么帮助?
制造商史蒂夫(Steve)

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

从几年前开始,已经有多个答案显示“联接多个表”。您的回答对讨论有什么帮助?
制造商史蒂夫(Steve)

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连接语法中的问题。我正在查看MySql是否专门支持ansi连接语法。
拉里·史密斯

0

不要那样参加。这是一个非常糟糕的做法!!!这将减慢海量数据获取的性能。例如,如果每个表中有100行,则数据库服务器必须获取100x100x100 = 1000000时间。它不得不取回1 million时间。为了解决该问题,请加入前两个表,以尽可能减少匹配的结果(取决于数据库架构)。在Subquery中使用该结果,然后将其与第三个表连接并获取它。对于第一个连接-> 100x100= 10000次,假设我们得到5个匹配结果。然后,我们将第三个表与结果-> 仅5x100 = 500.提取= 10000+500 = 10200次连接起来。因此,性能提高了!!!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.