انضم إلى صف واحد من جدول في MySQL
-
30-09-2019 - |
سؤال
انا لدي طاولتان players
و scores
.
أريد إنشاء تقرير يشبه هذا:
player first score points
foo 2010-05-20 19
bar 2010-04-15 29
baz 2010-02-04 13
في الوقت الحالي ، يبدو استفساري شيئًا كهذا:
select p.name player,
min(s.date) first_score,
s.points points
from players p
join scores s on s.player_id = p.id
group by p.name, s.points
أحتاج ال s.points
وهذا يرتبط بالصف الذي min(s.date)
عائدات. هل يحدث هذا مع هذا الاستعلام؟ هذا هو ، كيف يمكنني أن أكون متأكدًا من أنني أحصل على الصحيح s.points
قيمة للصف المنضم؟
ملاحظة جانبية: أتصور أن هذا يرتبط بطريقة ما بافتقار MySQL إلى الترتيب الكثيف. ما هو أفضل حلول هنا؟
المحلول
هذه هي أكبر مشكلة في المجموعة التي تظهر بشكل متكرر على سعة مكدس.
ها هي إجابتي المعتادة:
select
p.name player,
s.date first_score,
s.points points
from players p
join scores s
on s.player_id = p.id
left outer join scores s2
on s2.player_id = p.id
and s2.date < s.date
where
s2.player_id is null
;
وبعبارة أخرى ، حاول أن تجد درجة S2 لنفس اللاعب ، ولكن مع تاريخ سابق. إذا لم يتم العثور على نتيجة سابقة ، فإن S هي أقرب درجة.
إعادة تعليقك حول العلاقات: يجب أن يكون لديك سياسة تستخدمها في حالة التعادل. أحد الاحتمالات هو إذا كنت تستخدم المفاتيح الأولية المتمثلة في التلقائي ، فإن المفاتيح ذات القيمة الأقل هي المفاتيح السابقة. شاهد المصطلح الإضافي في الانضمام الخارجي أدناه:
select
p.name player,
s.date first_score,
s.points points
from players p
join scores s
on s.player_id = p.id
left outer join scores s2
on s2.player_id = p.id
and (s2.date < s.date or s2.date = s.date and s2.id < s.id)
where
s2.player_id is null
;
تحتاج بشكل أساسي إلى إضافة مصطلحات التعادل إلى أن تصل إلى عمود مضمون ليكون فريدًا ، على الأقل بالنسبة للاعب المعطى. غالبًا ما يكون المفتاح الأساسي للجدول هو الحل الأفضل ، لكنني رأيت حالات يكون فيها عمودًا آخر مناسبًا.
فيما يتعلق بالتعليقات التي شاركتها مع Ponies OMG ، تذكر أن هذا النوع من الاستعلام يعود بشكل كبير من الفهرس الصحيح.
نصائح أخرى
لن يسمح لك معظم RDMBs بتضمين أعمدة غير مجمعة في جملة SELECT عند استخدام Group by. في MySQL ، سوف ينتهي بك الأمر بقيم من صفوف عشوائية للأعمدة غير المجمعة. هذا مفيد إذا كان لديك بالفعل نفس القيمة في عمود معين لجميع الصفوف. لذلك ، من الجيد أن MySQL لا يقيدنا ، على الرغم من أنه من المهم فهمه.
يكرس فصل كامل لهذا في SQL antepatterns.