Unindo três tabelas usando MySQL

117

Eu tenho três tabelas nomeadas

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

Agora para mostrar o nome do aluno com o nome do curso que ele estudou,

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

Eu construo a seguinte consulta

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

Mas não retorna o resultado exigido ...

E o que seria de forma normalizada, se eu quiser descobrir quem é o gerente sobre os outros:

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

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

E deseja obter este resultado:

**result**
--------------------
Manager      Staff
--------------------
ali          king
ali          mak
mak          sam
sam          jon
PHP Ferrari
fonte
no primeiro resultado, você configurou dados incorretamente para ahmed e ali
NineCattoRules

Respostas:

199

Use a sintaxe ANSI e ficará muito mais claro como você está juntando as tabelas:

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
fonte
9
@Muhammad: Nossas respostas são as mesmas, elas diferem apenas na sintaxe. Se você não está ciente da ANSIsintaxe, vale a pena aprender. Isso o ajudará a evitar JOINerros como os que você cometeu no futuro.
RedFilter
16

Para normalizar a forma

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
fonte
A ordem importa em m.mid = e1.ide m.eid = e2.id?
Pathros
1
@Pathros Não, a ordem não importa, nessas expressões.
Toolmaker Steve
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
fonte
Essa resposta é muito semelhante às respostas já dadas 5 anos antes. O que você acha da sua resposta importante e ausente nas respostas existentes?
Toolmaker Steve
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;

Você pode JUNTAR várias TABELAS como este exemplo acima.

sameerNAT
fonte
Já existem várias respostas, de anos anteriores, que mostram "juntar várias mesas". O que sua resposta adiciona à discussão?
Toolmaker Steve
0

Consulta para juntar mais de duas tabelas:

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
fonte
Já existem várias respostas, de anos anteriores, que mostram "juntar várias mesas". O que sua resposta adiciona à discussão?
ToolmakerSteve
0

Usa isto:

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
fonte
1
Esta resposta não adiciona nada de novo a esta questão e usa uma sintaxe estranha (se não for uma sintaxe totalmente errada, eu ficaria surpreso se isso fosse válido no MySQL).
AeroX de
Eu discordo do AeroX. A sintaxe de junção Ansi tem como objetivo eliminar a ambiguidade de problemas com a sintaxe da vírgula / where join da velha escola. Estou procurando ver se o MySql oferece suporte especificamente à sintaxe de junção ansi.
Larry Smith de
0

Não entre assim. É uma prática realmente muito ruim !!! Isso vai diminuir o desempenho na busca com dados massivos. Por exemplo, se houver 100 linhas em cada tabela, o servidor de banco de dados terá que buscar 100x100x100 = 1000000horários. Teve que valer por 1 millionvezes. Para superar esse problema, junte as duas primeiras tabelas que podem buscar o resultado na correspondência mínima possível (depende do esquema do seu banco de dados). Use esse resultado na Subconsulta e, em seguida, junte-o à terceira tabela e busque-o. Para a primeira junção -> 100x100= 10000vezes e suponha que tenhamos 5 resultados correspondentes. E então juntamos a terceira tabela com o resultado -> 5x100 = 500.Total fetch = 10000+500 = 10200times only. E assim, o desempenho subiu !!!

Dracula Oppa
fonte