سؤال

هيكل الجدول

id    |    message    |    reply_id
1     |    help me!   |    0
434   |    love to    |    1
852   |    didn't work |    434
0110  |    try this   |    852
2200  |    this wont  |    0
5465  |    done. :)   |    0110

لدي معرف "852" وهو قائمة منتصف الشجرة، لكنني أرغب في الحصول على جميع الصفوف ذات الصلة السابقة ذات الصلة والصف التالية، لذلك أريد الحصول على نتائج متابعة مثل هذا:

ساعدني! > الحب إلى> لم ينجح> جرب هذا> القيام به. :) (هذه النتيجة تظهر من هذا النحو بعد حلقة PHP، ولكنها تبدأ في الحلقات من معرف Starter 1 مع معرف الرد 0.

ملاحظة: 2200 معرف لم يظهر في النتيجة، لأنه ليس جزءا من المجموعة.

هل كانت مفيدة؟

المحلول

هناك العديد من البدائل لصنع معلومات هرمية أسهل في العمل مع SQL:

  • تعبيرات الجدول المشترك (لكل معيار SQL-2003) دعم استعلامات SQL العودية ضد نوع البيانات الأصلية للبيانات التي تستخدمها. حتى الآن، لا يدعم MySQL هذه الميزة. Postgresql 8.4، Microsoft SQL Server، و IBM DB2 هي أمثلة على العلامات التجارية RDBMS التي تدعم بناء جملة CTE. يحتوي Oracle أيضا على امتداد خاص لبوليات SQL يدعم الاستعلامات العودية.

  • مجموعات متداخلة (الحل الأيسر / الأيمن الذي يذكر ThantomBrain) هو حل مفصل في كتاب جو سيلكو "الأشجار والأهرافات في SQL ل SQL for Smarties" وأيضا في العديد من المقالات وعمليات المدونة على الإنترنت.

  • تعداد المسار (AKA المسار المخصص) يخزن سلسلة في كل صف في التسلسل الهرمي لملاحظة طريق أسلاف هذا الصف. الجمع بين هذا مع LIKE استفسارات لمقارنة سلسلة المسار إلى مسارات أسلافها ومسارات أحفادهم.

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

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

نصائح أخرى

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

يرى http://www.sitepoint.com/print/hierarchical-data-database/ للمزيد من المعلومات

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

CREATE TEMPORARY TABLE tbl (myid int, ViewOrder int); 
Set @ifoundID=IdYourLookingFor;
Set @iStartID=@ifoundID;
Set @iOrder=0;
INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);

BEGIN --get the ones going up
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=reply_id FROM YourTable WHERE id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder-1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

Set @ifoundID=@iStartID;
BEGIN --get the ones going down
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=id FROM YourTable WHERE reply_id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder+1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

SELECT * FROM tbl INNER JOIN YourTable ON tbl.myid=YourTable.id ORDER BY ViewOrder

امل ان يساعد

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top