محتويات الدورة

MySQL / الأسس العلائقية و SQL الدقيقة / الدرس 3

الربط وعددية العلاقات

اجمع الحقائق المرتبطة مع الحفاظ على عدد صفوف النتيجة المقصود.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • ميّز الربط الداخلي والأيسر والمتقاطع ببيانات المتجر.
  • حدد مصدر التكرار واحفظ العملاء الذين لا يملكون طلبات.

اختر مستوى صف النتيجة

استخدم البيانات الأصلية دون تعديل. حدد أولاً ما يمثله صف النتيجة: عميل أم طلب أم بند طلب. يعيد الربط الداخلي صفاً لكل زوج مطابق، وقد يزيد العدد دون خطأ. يطابق العميل 1 طلبين؛ وينتج ربطهما بالبـنود ثلاثة صفوف لهذا العميل. هذه الزيادة سلوك علائقي وليست عيباً.

اربط المفاتيح لا التسميات

اكتب JOIN ... ON صراحة وأهل أسماء الأعمدة المتكررة بأسماء الجداول المستعارة. يتبع ربط orders.customer_id مع customers.id العلاقة المعلنة. أما ربط orders.id مع customers.id فصحيح نحوياً وخاطئ معنًى. وتخضع المساواة لقواعد الأنواع والمقارنة، مما يعزز تجنب النص غير المنضبط كمفتاح علاقة.

sql اسم عميل واحد لكل طلب
SELECT o.id AS order_id, c.name, o.total
FROM orders AS o JOIN customers AS c ON c.id = o.customer_id
ORDER BY o.id;
الناتج المتوقع
order_id | name | total
101 | Amina | 25.00
102 | Amina | 30.00
103 | Leo | 10.00

تحتوي النتيجة على 101/Amina/25.00 و 102/Amina/30.00 و 103/Leo/10.00. يتكرر اسم Amina لأن مستوى النتيجة هو الطلبات. يضمن تفرد العميل اسماً واحداً لكل طلب؛ ويُبطل جدول بحث غير فريد هذا الافتراض.

احفظ العملاء غير المطابقين

يحفظ الربط الأيسر كل صفوف الجانب الأيسر، وتصبح أعمدة الجانب الأيمن NULL عند عدم وجود تطابق. وقد تزيل تصفية عمود أيمن داخل WHERE الصفوف المحفوظة فتشترط التطابق عملياً. ضع الشرط داخل ON عندما يحدد الصفوف اليمنى المسموح بمطابقتها مع الاحتفاظ بكل العملاء. الموضعان يجيبان عن سؤالين مختلفين.

sql كل العملاء مع الطلبات المدفوعة فقط
SELECT c.id, c.name, o.id AS paid_order
FROM customers AS c
LEFT JOIN orders AS o ON o.customer_id = c.id AND o.status = 'paid'
ORDER BY c.id, o.id;
الناتج المتوقع
id | name | paid_order
1 | Amina | 101
2 | Leo | 103
3 | Noor | NULL

تطابق Amina الطلب 101 و Leo الطلب 103 وتبقى Noor بقيمة NULL في paid_order. نقل o.status = 'paid' إلى WHERE يزيل Noor لأن المقارنة مع NULL الناتجة مجهولة. ولا يطابق الطلب الجديد 102 شرط الدفع.

استخدم الوجود عند الحاجة

لعرض العملاء دون طلب استخدم NOT EXISTS بشرط مترابط على customer_id. فهو يعبّر عن الغياب دون بناء صفوف طلب غير لازمة. ويصح أيضاً الربط الأيسر مع WHERE o.id IS NULL لأن رقم الطلب المخزن لا يكون NULL. أما اختبار عمود وصفي قابل للغياب فيخلط غياب الصف بوجود صف يحوي معلومة مفقودة.

احم الإجماليات من تضاعف الصفوف

يكرر ربط إجماليات الطلبات بالبـنود إجمالي الطلب مع كل بند. ويؤدي جمع القيم المكررة إلى 90.00 بدلاً من الإجمالي الصحيح 65.00. اجمع البنود حسب الطلب قبل مقارنتها بإجمالي الطلب. وليست DISTINCT حلاً عاماً، فقد تتساوى إجماليات طلبين مختلفين بصورة صحيحة. تحقق من الأعداد ومفتاح كل مرحلة وسيطة.

الأخطاء الشائعة وإصلاحها

ERROR 1052 (23000): Column is ambiguous.

لماذا يحدث؟
يضم الجدولان عمود id ولم يُحدد مصدره.
كيف تصلحه؟
استخدم c.id أو o.id حسب الكيان المطلوب.
كيف تتجنب تكراره؟
أهّل أعمدة العلاقات باستمرار بما فيها ORDER BY.

يظهر كل عميل مع كل طلب.

لماذا يحدث؟
أنتج غياب شرط الربط حاصل ضرب ديكارتي: ثلاثة في ثلاثة صفوف.
كيف تصلحه؟
أضف ON o.customer_id = c.id ثم أعد عدّ التطابقات.
كيف تتجنب تكراره؟
توقع العددية قبل قبول نتائج تبدو معقولة.

اختفاء العملاء الذين لا يملكون طلبات مدفوعة.

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

اختبر فهمك

1. اعرض العملاء دون طلبات وتوقع النتيجة.

اعرض الحل المشروح

يعيد SELECT c.id, c.name FROM customers c WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id) ORDER BY c.id الصف 3/Noor فقط. يسأل الاستعلام الفرعي عن وجود أي صف مطابق؛ ولا يعد SELECT 1 الطلبات ولا يعرضها.

2. لماذا ينتج ربط الطلبات بالبـنود أربعة صفوف لا ثلاثة؟

اعرض الحل المشروح

يسهم الطلب 101 ببندين ويسهم كل من 102 و 103 ببند واحد. مستوى صف الربط هو مفتاح البند المركب وليس رقم الطلب وحده. للحصول على صف لكل طلب اجمع الصفوف الأربعة حسب order_id أو اربط علاقة بنود مجمعة مسبقاً.

أهم ما تعلمته

  • حدد مستوى الصف وأهّل المفاتيح قبل الربط.
  • تتحكم ON في المطابقة وتصفي WHERE الصفوف الناتجة.

المراجع الرسمية