شرح - sql join 3 tables




ما الفرق بين "INNER JOIN" و "OUTER JOIN"؟ (20)

ما الفرق بين "INNER JOIN" و "OUTER JOIN"؟

هم المشغلين الوجوديين الأكثر استخدامًا في SQL ، حيث INNER JOINيتم استخدام "موجود" LEFT OUTER JOINويستخدم "غير موجود".

خذ بعين الاعتبار هذه الاستعلامات:

users who have posted and have votes
users who have posted but have no badges

الأشخاص الذين يبحثون عن الحلول المستندة إلى مجموعة (مصطلح الصناعة) يمكنهم التعرف على الاستعلامات المعنية على النحو التالي:

users who have posted INTERSECT users who have votes
users who have posted MINUS users who have badges

ترجمة هذه إلى SQL القياسي:

SELECT UserId FROM Posts
INTERSECT 
SELECT UserId FROM Votes;

SELECT UserId FROM Posts
EXCEPT 
SELECT UserId FROM Badges;

سوف يفكر آخرون على طول الخطوط المتشابهة لتضمين المجموعة:

users who have posted and IN the set of users who have votes
users who have posted and NOT IN the set of users who have badges

ترجمة هذه إلى SQL القياسي:

SELECT UserId 
  FROM Posts
 WHERE UserId IN ( SELECT UserId FROM Votes );

SELECT UserId 
  FROM Posts
 WHERE UserId NOT IN ( SELECT UserId FROM Badges );

سوف يفكر البعض من حيث "الوجود" داخل مجموعات على سبيل المثال

users who have posted and EXIST in the set of users who have votes
users who have posted and do NOT EXIST in the set of users who have badges

ترجمة هذه إلى SQL القياسي (لاحظ أننا الآن بحاجة إلى استخدام متغيرات النطاق مثل p، v، b):

SELECT p.UserId 
  FROM Posts p
 WHERE EXISTS ( SELECT *
                  FROM Votes v
                 WHERE v.UserId = p.UserId );

SELECT p.UserId 
  FROM Posts p
 WHERE NOT EXISTS ( SELECT *
                      FROM Badges b
                     WHERE b.UserId = p.UserId );

ومع ذلك ، لقد وجدت أن نهج "الصناعة القياسية" هو استخدام الصلات حصرا. لا أعرف ما هو الفكر هنا ( قانون الصك ؟ التحسين المبكر ؟) ، لذلك سأذهب مباشرة إلى بناء الجملة:

SELECT p.UserId 
  FROM Posts p
       INNER JOIN Votes v ON v.UserId = p.UserId;

SELECT p.UserId 
  FROM Posts p
       LEFT JOIN Badges b ON b.UserId = p.UserId
 WHERE b.UserId IS NULL;

أشياء يجب ملاحظتها:

  • الإسقاط الوحيد هو من Usersولكن ما زلنا بحاجة إلى كل هذه المتغيرات المدى ( p، v، b) لظروف البحث.
  • في UserId IS NULLحالة بحث "ينتمي" إلى و OUTER JOINلكن يتم قطع في الاستعلام.
  • LEFTهو معيار الصناعة: سيعيد المحترفون كتابة استعلام لتجنب الاستخدام RIGHT!
  • في OUTERالكلمة من LEFT OUTER JOINيتم حذف.

ملاحظات ختامية:

يتم استخدام الصلات أحيانًا في الاستعلامات فقط لتحديد ما إذا كانت القيم موجودة أو غير موجودة في مجموعة أخرى. تعلم أن تنظر بعناية في الخصائص التي يتم إسقاطها (الأعمدة في SELECTالجملة): إذا لم يكن هناك أي من الجدول المرتبط ، فسيتم استخدامها ببساطة كمشغلات موجودة. بالإضافة إلى صلة خارجية ، ابحث عن مثيلات <key_column> IS NULLفي WHEREجملة.

أيضًا كيف يمكن LEFT JOIN و " RIGHT JOIN و FULL JOIN ؟


صلة داخلية

استرداد الصفوف المتطابقة فقط ، وهذا يعني ، A intersect B

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

ترك صلة خارجية

حدد كافة السجلات من الجدول الأول ، وأي سجلات في الجدول الثاني تطابق المفاتيح المتصلة.

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

الانضمام الخارجي الكامل

حدد كافة السجلات من الجدول الثاني ، وأي سجلات في الجدول الأول تطابق المفاتيح المتصلة.

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

المراجع


الرسوم البيانية Venn لا تفعل ذلك حقا بالنسبة لي.

وهي لا تظهر أي تمييز بين الانضمام المتقاطع والانضمام الداخلي ، على سبيل المثال ، أو بشكل عام إظهار أي تمييز بين أنواع مختلفة من دالة الربط أو توفير إطار للتفكير حول كيفية عملها.

لا يوجد بديل لفهم المعالجة المنطقية وأنه من السهل نسبياً فهمها على أي حال.

  1. تخيل صليب الانضمام.
  2. تقييم جملة on مقابل كافة الصفوف من الخطوة 1 حفظ تلك حيث تقيم التقييم إلى true
  3. (بالنسبة إلى الصلات الخارجية فقط) ، أضف أيًا من الصفوف الخارجية التي فقدت في الخطوة 2.

(ملاحظة: في الممارسة العملية ، قد يجد مُحسِّن الاستعلام طرقًا أكثر فعالية لتنفيذ الاستعلام من الوصف المنطقي البحت أعلاه ولكن يجب أن تكون النتيجة النهائية هي نفسها)

سأبدأ مع نسخة متحركة من صلة خارجية كاملة . يتبع شرح لاحق.

تفسير

جداول المصدر

تبدأ أولا مع CROSS JOIN (AKA منتج الديكارتية). هذا ليس لديه جملة ON وبسهولة إرجاع كل تركيبة من الصفوف من الجدولين.

SELECT A.Colour، B.Colour FROM A CROSS JOIN B

صلة الداخلية والخارجية تحتوي على مسند جملة "ON".

  • صلة داخلية. تقييم الشرط في جملة "ON" لجميع الصفوف في النتيجة الانضمام الصليب. إذا كان صحيحا إرجاع الصف انضم. خلاف ذلك تجاهلها.
  • ترك صلة خارجية. نفس الانضمام الداخلي ثم أي صفوف في الجدول الأيسر لم تطابق أي شيء إخراج هذه مع قيم فارغة لعمود الجدول الأيمن.
  • اليمين الخارجي تاريخ. نفس الانضمام الداخلي ثم أي صفوف في الجدول الأيمن لا تطابق أي شيء إخراج هذه مع قيم فارغة لعمود الجدول الأيسر.
  • الانضمام الخارجي الكامل. تمامًا كالانضمام الداخلي ، ثم احتفظ بالصفوف اليسرى غير المتطابقة كما هو الحال في الصفوف الخارجية لجهة اليسار واليمين غير المطابقة لكل صلة خارجية صحيحة.

بعض الأمثلة

SELECT A.Colour، B.Colour FROM A INNER JOIN B ON A.Colour = B.Colour

ما ورد أعلاه هو الانضمام equi الكلاسيكية.

النسخة المتحركة

SELECT A.Colour، B.Colour FROM A INNER JOIN B ON A.Colour NOT IN ('Green'، 'Blue')

لا يلزم بالضرورة أن يكون شرط الربط الداخلي شرطًا للمساواة ولا يحتاج إلى مرجع الأعمدة من كلا الجدولين (أو حتى أحدهما). تقييم A.Colour NOT IN ('Green','Blue') على كل صف من عناصر cross join.

SELECT A.Colour، B.Colour FROM A INNER JOIN B ON 1 = 1

يتم تقييم الشرط الصلة إلى true لكافة الصفوف في نتيجة الانضمام المتصالب ، بحيث يكون هذا هو نفس الارتباط المتقاطع فقط. لن أكرر صورة الصفوف الستة عشر مرة أخرى.

SELECT A.Colour، B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour

يتم تقييم عمليات الربط الخارجي منطقياً بنفس طريقة الصلات الداخلية فيما عدا أنه إذا لم ينضم صف من الجدول الأيسر (للارتباط الأيسر) مع أي صفوف من الجدول اليدوي على الإطلاق فإنه يتم حفظه في النتيجة بقيم NULL لـ أعمدة اليد اليمنى.

SELECT A.Colour، B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour IS NULL

هذا ببساطة يقيد النتيجة السابقة لإعادة الصفوف فقط حيث B.Colour IS NULL . في هذه الحالة بالذات ، ستكون هذه الصفوف التي تم حفظها لأنها لا تطابق في الجدول اليدوي ويعيد الاستعلام الصف الأحمر الواحد غير المتطابق في الجدول B . هذا هو المعروف باسم مكافحة شبه الانضمام.

من المهم تحديد أحد الأعمدة لاختبار IS NULL غير القابل للبلوغ أو الذي يضمن شرط الربط أن يتم استبعاد أي قيم NULL لكي يعمل هذا النمط بشكل صحيح ويتجنب فقط إعادة الصفوف التي يحدث أن يكون لها قيمة NULL لهذا العمود بالإضافة إلى الصفوف غير المتطابقة.

SELECT A.Colour، B.Colour FROM A RIGHT OUTER JOIN B ON A.Colour = B.Colour

تعمل الصلات الخارجية اليمنى بشكل مشابه للارتباطات الخارجية اليسرى باستثناء أنها تحافظ على الصفوف غير المطابقة من الجدول الأيمن وتمدد الأصفار اليسرى.

SELECT A.Colour، B.Colour FROM A FULL OUTER JOIN B ON A.Colour = B.Colour

تجمع الصلات الخارجية الكاملة بين سلوك الصلات اليمنى واليسرى وتحافظ على الصفوف غير المطابقة من كل من اليسار واليمين.

SELECT A.Colour، B.Colour FROM A FULL OUTER JOIN B ON 1 = 0

لا توجد صفوف في cross join تطابق 1=0 المسند. يتم الاحتفاظ كافة الصفوف من كلا الجانبين باستخدام قواعد الانضمام الخارجي العادي مع NULL في الأعمدة من الجدول على الجانب الآخر.

SELECT COALESCE (A.Colour، B.Colour) AS Color from A FULL OUTER JOIN B ON 1 = 0

مع تعديل طفيف على الاستعلام السابق يمكن للمرء محاكاة UNION ALL من الجدولين.

SELECT A.Colour، B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour = 'Green'

لاحظ أن WHERE (إذا كانت موجودة) تعمل بشكل منطقي بعد الانضمام. يتمثل أحد الأخطاء الشائعة في إجراء صلة خارجية يسرى ثم تضمين جملة WHERE مع شرط في الجدول الأيمن ينتهي باستبعاد الصفوف غير المتطابقة. وينتهي الأمر أعلاه بالقيام بالانضمام الخارجي ...

... ثم يتم تشغيل جملة "أين". لا يتم تقييم NULL= 'Green' إلى true حتى ينتهي الصف المحمي بواسطة الربط الخارجي إلى الأعلى (مع اللون الأزرق) بشكل فعال تحويل الارتباط مرة أخرى إلى واحد داخلي.

إذا كان القصد هو تضمين صفوف فقط من B حيث يكون اللون أخضر وجميع الصفوف من A بغض النظر عن الصيغة الصحيحة

SELECT A.Colour، B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour AND B.Colour = 'Green'

SQL كمان

انظر هذه الأمثلة على الهواء مباشرة في SQLFiddle.com .


بافتراض أنك تنضم إلى الأعمدة بدون تكرار ، وهي حالة شائعة جدًا:

  • يعطي الاندماج الداخلي لـ A و B نتيجة التقاطع B ، أي الجزء الداخلي من تقاطع Venn .

  • يعطي الرابط الخارجي لـ A و B نتائج الاتحاد B ، أي الأجزاء الخارجية لاتحاد رسم بياني Venn.

أمثلة

افترض أن لديك جدولين ، مع كل عمود واحد ، والبيانات على النحو التالي:

A    B
-    -
1    3
2    4
3    5
4    6

لاحظ أن (1،2) فريدة من نوعها بالنسبة إلى A ، (3،4) شائعة ، و (5،6) تكون فريدة بالنسبة إلى B.

صلة داخلية

توفر الصلة الداخلية باستخدام أي من الاستعلامات المكافئة تقاطع الجدولين ، أي الصفين المشترك بينهما.

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

a | b
--+--
3 | 3
4 | 4

ترك صلة خارجية

سيعطي صلة خارجية اليسار كافة الصفوف في A ، بالإضافة إلى أي صفوف شائعة في B.

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4

الانضمام الخارجي الصحيح

ستوفر صلة خارجية صحيحة كل الصفوف في B ، بالإضافة إلى أي صفوف مشتركة في A.

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6

الانضمام الخارجي الكامل

سيعطيك الرابط الخارجي الكامل اتحاد A و B ، أي جميع الصفوف في A وجميع الصفوف في B. إذا كان هناك شيء في A لا يحتوي على مسند مناظر في B ، فإن الجزء B فارغ ، والعكس بالعكس.

select * from a FULL OUTER JOIN b on a.a = b.b;

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5

بكلمات بسيطة:

انضمام داخلي -> خذ سجلات شائعة فقط من جداول الوالدين والطفل حيث يوجد المفتاح الأساسي لمطابقة الجدول الأصل مع المفتاح الخارجي في جدول الطفل.

انضمام اليسار ->

رمز زائف

1.Take All records from left Table
2.for(each record in right table,) {
    if(Records from left & right table matching on primary & foreign key){
       use their values as it is as result of join at the right side for 2nd table.
    } else {
       put value NULL values in that particular record as result of join at the right side for 2nd table.
    }
  }

الانضمام إلى اليمين : تمامًا عكس الانضمام إلى اليسار. ضع اسم الجدول في LEFT JOIN في الجانب الأيمن في الانضمام إلى اليمين ، تحصل على نفس النتيجة مثل LEFT JOIN.

صلة خارجية : إظهار كافة السجلات في كلا الجدولين No matter what . إذا كانت السجلات الموجودة في الجدول الأيسر غير مطابقة للجدول الأيمن استنادًا إلى المفتاح الأساسي أو المفتاح الأمامي ، فقم باستخدام قيمة NULL كنتيجة الصلة.

مثال:

دعونا نفترض الآن لجداول 2

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

هنا ، جدول الموظفين هو الجدول الرئيسي ، phone_numbers_employees هو الجدول التابع (يحتوي على emp_idالمفتاح الخارجي الذي يربط employee.idذلك الجدول التابع الخاص به.)

ينضم الداخلي

خذ سجلات جدولين فقط إذا كان المفتاح الأساسي من جدول الموظفين (معرفه) يتطابق مع المفتاح الخارجي لـ هاتف الجدول التابع لـ phone_numbers_employees (emp_id) .

لذلك سوف يكون الاستعلام:

SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

هنا تأخذ فقط الصفوف المطابقة على المفتاح الأساسي = المفتاح الخارجي كما هو موضح أعلاه. هنا يتم تخطي الصفوف غير المطابقة على المفتاح الأساسي = المفتاح الخارجي نتيجة الانضمام.

ينضم اليسار :

يحتفظ "الارتباط الأيسر" بجميع صفوف الجدول الأيسر ، بغض النظر عما إذا كان هناك صف يتطابق مع الجدول الأيمن.

SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

ينضم الخارجي :

SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

بشكل تخطيطي ، يبدو الأمر كما يلي:


تتطلب الصلات الداخلية وجود سجل له معرف مرتبط في الجدول المرتبط.

ستقوم الوصلات الخارجية بإرجاع السجلات للجانب الأيسر حتى إذا لم يكن هناك أي شيء للجانب الأيمن.

على سبيل المثال ، لديك "الطلبات" و "جدول OrderDetails". ترتبط بها "OrderID".

أوامر

  • رقم التعريف الخاص بالطلب
  • اسم الزبون

تفاصيل الطلب

  • OrderDetailID
  • رقم التعريف الخاص بالطلب
  • اسم المنتج
  • الكمية
  • السعر

الطلب

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

سيعود فقط الطلبات التي تحتوي أيضًا على شيء في جدول OrderDetails.

إذا قمت بتغييره إلى OUTER LEFT JOIN

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

ثم سيتم إرجاع السجلات من جدول "الطلبات" حتى إذا لم يكن لديهم سجلات OrderDetails.

يمكنك استخدام هذا للعثور على الطلبات التي ليس لديها أي OrderDetails تشير إلى ترتيب ممكن عزله بإضافة جملة حيث WHERE OrderDetails.OrderID IS NULL .


تم أخذ ما يلي من المقال " MySQL - LEFT JOIN و RIGHT JOIN، INNER JOIN و OUTER JOIN " بواسطة Graham Ellis على مدونة Horse's Mouth.

في قاعدة بيانات مثل MySQL ، يتم تقسيم البيانات إلى عدد من الجداول التي يتم وصلها بعد ذلك ( Joined ) معًا عن طريق JOIN في أوامر SELECT لقراءة السجلات من جداول متعددة. اقرأ هذا المثال لترى كيف يعمل.

أولا ، بعض بيانات العينة:

people
    mysql> select * from people;
    +------------+--------------+------+
    | name       | phone        | pid  |
    +------------+--------------+------+
    | Mr Brown   | 01225 708225 |    1 |
    | Miss Smith | 01225 899360 |    2 |
    | Mr Pullen  | 01380 724040 |    3 |
    +------------+--------------+------+
    3 rows in set (0.00 sec)

property
    mysql> select * from property;
    +------+------+----------------------+
    | pid  | spid | selling              |
    +------+------+----------------------+
    |    1 |    1 | Old House Farm       |
    |    3 |    2 | The Willows          |
    |    3 |    3 | Tall Trees           |
    |    3 |    4 | The Melksham Florist |
    |    4 |    5 | Dun Roamin           |
    +------+------+----------------------+
    5 rows in set (0.00 sec)

الانضمام العادي

إذا أجرينا عملية JOIN عادية (بدون أي من الكلمات الرئيسية INNER أو OUTER أو LEFT أو RIGHT) ، فسنحصل على جميع السجلات التي تتطابق بالطريقة المناسبة في الجدولين ، ولا يتم الإبلاغ عن السجلات في كل من الجداول الواردة غير المطابقة :

mysql> select name, phone, selling 
from people join property 
on people.pid = property.pid;
+-----------+--------------+----------------------+
| name      | phone        | selling              |
+-----------+--------------+----------------------+
| Mr Brown  | 01225 708225 | Old House Farm       |
| Mr Pullen | 01380 724040 | The Willows          |
| Mr Pullen | 01380 724040 | Tall Trees           |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+-----------+--------------+----------------------+
4 rows in set (0.01 sec)

انضم إلى اليسار

إذا فعلنا LEFT JOIN ، فإننا نحصل على جميع السجلات التي تطابق بنفس الطريقة ، وإضافة إلى ذلك ، نحصل على سجل إضافي لكل سجل غير متطابق في الجدول الأيسر للنص - مما يضمن (في هذا المثال) أن كل شخص يحصل على ذكر :

   mysql> select name, phone, selling 
    from people left join property 
    on people.pid = property.pid; 
    +------------+--------------+----------------------+
    | name       | phone        | selling              |
    +------------+--------------+----------------------+
    | Mr Brown   | 01225 708225 | Old House Farm       |
    | Miss Smith | 01225 899360 | NULL <<-- unmatch    |
    | Mr Pullen  | 01380 724040 | The Willows          |
    | Mr Pullen  | 01380 724040 | Tall Trees           |
    | Mr Pullen  | 01380 724040 | The Melksham Florist |
    +------------+--------------+----------------------+
    5 rows in set (0.00 sec)

الانضمام إلى اليمين

إذا فعلنا RIGHT JOIN ، فإننا نحصل على جميع السجلات التي تطابق و IN ADDITION سجلاً إضافياً لكل سجل لا مثيل له في الجدول الصحيح للإنضمام - في مثال ، هذا يعني أن كل خاصية تحصل على ذكر حتى لو لم نفعل لديك تفاصيل البائع:

mysql> select name, phone, selling 
from people right join property 
on people.pid = property.pid;
+-----------+--------------+----------------------+
| name      | phone        | selling              |
+-----------+--------------+----------------------+
| Mr Brown  | 01225 708225 | Old House Farm       |
| Mr Pullen | 01380 724040 | The Willows          |
| Mr Pullen | 01380 724040 | Tall Trees           |
| Mr Pullen | 01380 724040 | The Melksham Florist |
| NULL      | NULL         | Dun Roamin           |
+-----------+--------------+----------------------+
5 rows in set (0.00 sec)

ينضم INNER JOIN إلى ارتباط كامل ، تمامًا مثل المثال الأول ، وقد تتم إضافة كلمة OUTER بعد الكلمة LEFT أو RIGHT في المثالين الأخيرين - يتم توفيرها لتوافق ODBC ولا تضيف إمكانات إضافية.



  • INNER JOINالانضمام الأكثر شيوعًا لجدولين أو أكثر. تقوم بإرجاع تطابق البيانات على كل من المفتاحين ON المفتاح الأساسي وعلامة forignkey.
  • OUTER JOINهو نفسه INNER JOIN، لكنه يتضمن أيضًا NULLبيانات على ResultSet.
    • LEFT JOIN= INNER JOIN+ بيانات غير متطابقة من الجدول الأيسر مع مطابقة Null في الجدول الصحيح.
    • RIGHT JOIN= INNER JOIN+ بيانات غير متطابقة من الجدول الصحيح مع مباراة خالية في الجدول الأيسر.
    • FULL JOIN= INNER JOIN+ بيانات غير متطابقة على كل من الجداول اليمنى واليسرى مع تطابقات فارغة.
  • الارتباط الذاتي ليست كلمة أساسية في SQL ، عندما يشير جدول البيانات في حد ذاته يعرف الارتباط الذاتي. باستخدام INNER JOINو OUTER JOINيمكن أن نكتب النفس الانضمام استفسار.

فمثلا:

SELECT * 
FROM   tablea a 
       INNER JOIN tableb b 
               ON a.primary_key = b.foreign_key 
       INNER JOIN tablec c 
               ON b.primary_key = c.foreign_key 


أبسط التعاريف

الانضمام الداخلي: إرجاع السجلات المتطابقة من كلا الجدولين.

الانضمام الكامل الخارجي: إرجاع السجلات المتطابقة وغير المتطابقة من كلا الجدولين مع فارغة للسجلات غير المتطابقة من كلا الجداول .

Left Outer Join: إرجاع السجلات المتطابقة وغير المتطابقة فقط من الجدول في الجانب الأيسر .

Right Outer Join: إرجاع السجلات المتطابقة وغير المتطابقة فقط من الجدول في الجانب الأيمن .

بالمختصر

متطابق + يسار غير متطابق + حق لا مثيل له = كامل خارجي صلة

متطابق + يسار غير متطابق = يسار خارجي صلة

المتطابقة + حق لا مثيل له = اليمين الخارجي صلة

مطابق = انضمام داخلي


الانضمام الداخلي تركز صلة داخلية على القواسم المشتركة بين جدولين. عند استخدام صلة داخلية ، يجب أن يكون هناك على الأقل بعض البيانات المتطابقة بين جدولين (أو أكثر) يتم مقارنتها. تقوم الصلة الداخلية بالبحث عن جداول لمطابقة أو تراكب البيانات. عند العثور عليه ، تجمع الصلة الداخلية وترجع المعلومات إلى جدول واحد جديد.

ربط خارجي ترجع صلة خارجية مجموعة من السجلات (أو الصفوف) التي تتضمن ما يعود به صلة داخلية ، ولكنها تتضمن أيضًا صفوفًا أخرى لم يتم العثور على تطابق مطابق لها في الجدول الآخر.

هناك ثلاثة أنواع من الصلات الخارجية:

Left الخارجي Join (أو Left Join) Right Outer Join (أو Right Join) Full Outer Join (أو الانضمام الكامل) كل من هذه الصلات الخارجية يشير إلى جزء من البيانات التي يتم مقارنتها ، ودمجها ، وإعادتها. في بعض الأحيان يتم إنتاج الأصفار في هذه العملية حيث تتم مشاركة بعض البيانات بينما لا تكون البيانات الأخرى.


صلة داخلية

ينتج عن الصلة الداخلية مجموعة نتائج تقتصر على الصفوف حيث يوجد تطابق في كلا الجدولين لما نبحث عنه. إذا كنت لا تعرف نوع الانضمام الذي تحتاج إليه ، فعادةً ما يكون هذا هو أفضل رهان.

ترك صلة خارجية

وينتج عن الارتباط الخارجي الأيسر ، أو الانضمام إلى اليسار ، مجموعة حيث يتم الاحتفاظ بكافة الصفوف من الجدول الأول أو الجانب الأيسر. لا تظهر الصفوف من الجدول الثاني أو الجانب الأيمن إلا إذا كان هناك تطابق مع الصفوف من الجدول الأول. في حالة وجود قيم من الجدول الأيسر ولكن ليس من اليمين ، سيقرأ الجدول قيمة خالية ، مما يعني أنه لم يتم تعيين القيمة.

RIGHT OUTER JOIN

الصلة الخارجية الصحيحة ، أو الربط الأيمن ، هي نفس الصلة اليسرى ، فيما عدا عكس الأدوار. تظهر جميع الصفوف من الجدول الأيمن في النتيجة ، ولكن الصفوف من الجدول الموجود على اليسار موجودة فقط إذا كانت مطابقة للجدول الموجود على اليمين. المساحات الفارغة خالية ، تمامًا كما هو الحال مع الرابط الأيسر.

الكامل الخارج الانضمام

ينشئ صلة خارجية كاملة أو صلة خارجية فقط مجموعة نتائج مع كافة الصفوف من كلا الجدولين ، بغض النظر عن ما إذا كانت هناك أية تطابقات. وبالمثل بالنسبة إلى الصلات اليسرى واليمنى ، فإننا نطلق على المساحات الخالية فارغة.

لمزيد من Reference


الجواب في معنى كل واحد ، لذلك في النتائج.

ملاحظة:
في SQLiteلا يوجد RIGHT OUTER JOINأو FULL OUTER JOIN.
وأيضا في MySQLلا يوجد FULL OUTER JOIN.

ويستند إجابتي على ملاحظة أعلاه .

عندما يكون لديك جدولين مثل هذين:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

CROSS JOIN / OUTER JOIN:
يمكنك الحصول على جميع هذه الجداول مع البيانات CROSS JOINأو مع ما ,يلي:

SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2
1  | a1   | 3  | b2
2  | b1   | 1  | a2
2  | b1   | 3  | b2

INNER JOIN:
عندما تريد إضافة فلتر إلى النتائج المذكورة أعلاه استنادًا إلى علاقة كما table1.id = table2.idيمكنك استخدام INNER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2

يسار [OUTER] JOIN:
عندما تريد الحصول على جميع الصفوف من أحد الجداول في النتيجة أعلاه ، مع نفس العلاقة ، يمكنك استخدام LEFT JOIN:
(لـ RIGHT JOIN فقط قم بتغيير مكان الجداول)

SELECT * FROM table1, table2 WHERE table1.id = table2.id 
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id   | name 
---+------+------+------
1  | a1   | 1    | a2
2  | b1   | Null | Null

FULL OUTER JOIN:
عندما تريد أيضًا الحصول على جميع صفوف الجدول الآخر في نتائجك ، يمكنك استخدام FULL OUTER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id

--[Results:]
id   | name | id   | name 
-----+------+------+------
1    | a1   | 1    | a2
2    | b1   | Null | Null
Null | Null | 3    | b2

حسنا ، حسب حاجتك تختار كل واحد يغطي حاجتك ؛).


الفرق هو في الطريقة التي يتم بها ربط الجداول إذا لم تكن هناك سجلات مشتركة.

JOINهو نفسه INNER JOINويعني فقط إظهار السجلات المشتركة بين الجدولين. يتم تحديد ما إذا كانت السجلات شائعة بواسطة الحقول الموجودة في جملة الصلة.

فمثلا:

SELECT * 
FROM t1
JOIN t2 on t1.ID = t2.ID

هذا يعني عرض السجلات فقط حيث توجد نفس IDالقيمة في كلا الجدولين.

LEFT JOINهو نفسه LEFT OUTER JOINويعني إظهار كافة السجلات من الجدول الأيسر (أي التي تسبق عبارة SQL) بغض النظر عن وجود سجلات متطابقة في الجدول الصحيح.

RIGHT JOINهو نفس RIGHT OUTER JOINويعني عكس LEFT JOIN، أي يعرض كل السجلات من الجدول الثاني (يمين) والسجلات المطابقة فقط من الجدول الأول (الأيسر).


الفرق هو في الطريقة التي يتم بها ربط الجداول إذا لم تكن هناك سجلات مشتركة.

  • JOINهو نفسه INNER JOINويعني فقط إظهار السجلات المشتركة بين الجدولين. يتم تحديد ما إذا كانت السجلات شائعة بواسطة الحقول الموجودة في جملة الصلة. فمثلا:

    FROM t1
    JOIN t2 on t1.ID = t2.ID
    

    يعني عرض السجلات فقط حيث توجد نفس IDالقيمة في كلا الجدولين.

  • LEFT JOINهو نفسه LEFT OUTER JOINويعني إظهار كافة السجلات من الجدول الأيسر (أي التي تسبق في عبارة SQL) بغض النظر عن وجود مطابقة السجلات في الجدول الصحيح.

  • RIGHT JOINهو نفس RIGHT OUTER JOINويعني عكس LEFT JOIN، أي يعرض كل السجلات من الجدول الثاني (يمين) والسجلات المطابقة فقط من الجدول الأول (الأيسر).

المصدر: ما الفرق بين اليسار واليمين والداخل والخارج؟


في شروط بسيطة ،

1. INNER JOIN أو EQUI JOIN: إرجاع resultset الذي يطابق الشرط في كلا الجدولين فقط.

2. الخارج صلة: إرجاع resultset جميع القيم من كلا الجدولين حتى لو كان هناك شرط مطابقة أم لا.

3. LEFT JOIN: إرجاع مجموعة النتائج لجميع القيم من الجدول الأيسر والصفوف التي تطابق الشرط الموجود في الجدول الأيمن فقط.

4. RIGHT JOIN: إرجاع مجموعة النتائج لجميع القيم من الجدول الصحيح والصفوف التي تطابق الشرط في الجدول الأيسر فقط.

5. الانضمام الكامل : الانضمام الكامل والالتحاق الخارجي الكامل هي نفسها.


لا أرى الكثير من التفاصيل حول الأداء والمحسن في الإجابات الأخرى.

في بعض الأحيان ، من الجيد أن تعرف أن هذا الأمر لا INNER JOINيعني سوى الارتباط ، وهو ما يعني أن للمحسن الخيار الأكبر للعب معه. يمكن إعادة ترتيب ترتيب الانضمام لجعله أسرع الاحتفاظ بنفس النتيجة. يمكن للمحسن استخدام معظم أوضاع الانضمام.

بشكل عام ، من الأفضل محاولة استخدام INNER JOINبدلاً من أنواع مختلفة من الصلات. (بالطبع إذا كان من الممكن النظر في مجموعة النتائج المتوقعة.)

هناك نوعان من الأمثلة الجيدة والشرح هنا حول هذا السلوك الترابطي الغريب:


الخوارزمية الدقيقة لـ INNER JOIN، LEFT/RIGHT OUTER JOINكما يلي:

  1. خذ كل صف من الجدول الأول: a
  2. النظر في جميع الصفوف من الجدول الثاني بجانبه: (a, b[i])
  3. تقييم ON ...الجملة مقابل كل زوج:ON( a, b[i] ) = true/false?
    • عندما يتم تقييم الشرط true، قم بإرجاع هذا الصف المدمج (a, b[i]).
    • عند الوصول إلى نهاية الجدول الثاني دون أي تطابق ، وهذا هو Outer Joinثم إرجاع زوج (ظاهري) يستخدم Nullلكافة أعمدة الجدول الآخر: (a, Null)لربط خارجي LEFT أو (Null, b)لارتباط خارجي RIGHT. هذا هو التأكد من وجود جميع صفوف الجدول الأول في النتائج النهائية.

ملاحظة:ON يمكن أن يكون الشرط المحدد في بند أي شيء ، وليس مطلوبًا استخدام المفاتيح الأساسية (ولا تحتاج دائمًا إلى الرجوع إلى الأعمدة من كلا الجدولين)! فمثلا:

  • ... ON T1.title = T2.title AND T1.version < T2.version(=> مشاهدة هذه المشاركة باعتبارها استخدام عينة: حدد الصفوف التي تحتوي على قيمة قصوى في عمود فقط )
  • ... ON T1.y IS NULL
  • ... ON 1 = 0 (مثلما العينة)

ملاحظة: لليسار صلة = يسار خارجية صلة ، يمين انضمام = يمين الخارجي صلة.


كنت تستخدم INNER JOINلإرجاع جميع الصفوف من كلا الجدولين حيث يوجد تطابق. أي في الجدول الناتج سيكون لكل الصفوف والأعمدة قيم.

في OUTER JOINالجدول الناتج قد تحتوي على أعمدة فارغة. صلة خارجية قد تكون إما LEFTأو RIGHT.

LEFT OUTER JOIN إرجاع كافة الصفوف من الجدول الأول ، حتى إذا لم توجد تطابقات في الجدول الثاني.

RIGHT OUTER JOIN إرجاع كافة الصفوف من الجدول الثاني ، حتى في حالة عدم وجود تطابقات في الجدول الأول.





outer-join