MySQL kullanarak üç tabloyu birleştirme


117

Adlı üç tablom var

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

Şimdi öğrencinin adını çalıştığı ders adıyla birlikte göstermek için,

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

Aşağıdaki sorguyu oluşturuyorum

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

Ancak gerekli sonucu döndürmüyor ...

Ve kimin diğerinin üzerinde yönetici olduğunu bulmak istersem normalleştirilmiş form için ne olurdu:

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

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

Ve bu sonucu almak istiyor:

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

ilk sonuçta ahmed ve ali için verileri yanlış ayarladınız
NineCattoRules

Yanıtlar:



199

ANSI sözdizimini kullanın ve tabloları nasıl birleştirdiğiniz çok daha net olacaktır:

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: Cevaplarımız aynı, sadece söz diziminde farklılık gösteriyorlar. ANSISözdiziminin farkında değilseniz , onu öğrenmek için zaman ayırmaya değer. JOINGelecekte yaptığınız gibi hatalardan kaçınmanıza yardımcı olacaktır .
RedFilter

16

Formu normalleştirmek için

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

Amacıyla önemli mi m.mid = e1.idve m.eid = e2.id?
Pathros

1
@Pathros Hayır, bu ifadelerde sıra önemli değil.
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

Bu cevap, 5 yıl önce verilen cevaplara çok benziyor. Cevabınızın önemli olduğunu ve mevcut cevaplarda eksik olduğunu düşünüyorsunuz?
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;

Yukarıdaki örnekte olduğu gibi birden çok TABLAYA KATILABİLİRSİNİZ.


Yıllar öncesinden "birden çok masaya katılmayı" gösteren birden çok yanıt zaten var. Cevabınız tartışmaya ne katıyor?
ToolmakerSteve

0

İkiden fazla tabloyu birleştirme sorgusu:

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

Yıllar öncesinden "birden çok masaya katılmayı" gösteren birden çok yanıt zaten var. Cevabınız tartışmaya ne katıyor?
ToolmakerSteve

0

Bunu kullan:

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
Bu cevap, bu soruya yeni bir şey eklemez ve garip kullanır (düz yanlış sözdizimi değilse, bu MySQL'de bile geçerli olsa şaşırırdım).
AeroX

AeroX'e katılmıyorum. Ansi birleştirme sözdizimi, eski okul virgül / nerede birleşim sözdizimi ile ilgili sorunları netleştirmek içindir. MySql'in özellikle ansi birleştirme sözdizimini destekleyip desteklemediğini görmek istiyorum.
Larry Smith

0

Böyle katılma. Gerçekten çok kötü bir uygulama !!! Çok büyük verilerle getirme performansını yavaşlatacaktır. Örneğin, her tabloda 100 satır varsa, veritabanı sunucusunun 100x100x100 = 1000000zamanları getirmesi gerekir . Bazen getirmesi gerekiyordu 1 million. Bu sorunun üstesinden gelmek için, mümkün olan minimum eşleştirme sonucunu getirebilecek ilk iki tabloyu birleştirin (bu, veritabanı şemanıza bağlıdır). Bu sonucu Alt Sorguda kullanın ve ardından üçüncü tabloyla birleştirip getirin. İlk birleştirme için -> 100x100= 10000kez ve 5 eşleşen sonuç aldığımızı varsayalım. Ve sonra sonuç -> 5x100 = 500.Toplam getirme = 10000+500 = 10200yalnızca zamanlar ile üçüncü tabloya katılıyoruz . Ve böylece performans arttı !!!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.