ما هو أفضل وسيلة لتجميع البيانات وشجرة الإجمالية والمبلغ؟

StackOverflow https://stackoverflow.com/questions/1610893

سؤال

وبالنظر إلى الجدول الرجوع إلى النفس

Item 
-------------
Id (pk)
ParentId (fk)

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

ItemValue
-------------
ItemId (fk)
Amount

وبعض البيانات النموذجية

Item                       ItemValues 
Id      ParentId           ItemId      Amount
--------------------       ----------------------
1       null               1           10
2       1                  3           40
3       1                  3           20
4       2                  4           10
5       2                  5           30
6       null
7       6
8       7

وأحتاج إلى sproc لاتخاذ Item.Id وعودة الأطفال مباشر مع مبالغ من كل ItemValue.Amounts للهم ولأبنائهم وأطفالهم على طول الطريق الشجرة.

وعلى سبيل المثال، إذا تم تمرير 1 في، سيتم 2, 3, 4, 5 الشجرة و2, 3 الأطفال المباشر من شأنه أن يكون الإخراج

 ItemId    Amount
 ------------------
 2         40     (values from ItemIds 4 & 5)
 3         60     (values from ItemId 3)

وأي نوع من النهج ينبغي تطبيقها لجعل تحقيق هذا السلوك؟

وأنا تفكر في استخدام CTE، ولكن أنا أتساءل إذا كان هناك / النهج الأفضل أسرع.

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

المحلول

وA CTE متكررة مثل هذا من شأنه أن يعمل، على افتراض التسلسل الهرمي الخاص بك لا تذهب عميقا جدا:

declare @ParentId int;
set @ParentId = 1;

;with 
  Recurse as (
    select 
      a.Id as DirectChildId
    , a.Id
    from Item a 
    where ParentId = @ParentId
    union all
    select
      b.DirectChildId
    , a.Id
    from Item a 
    join Recurse b on b.Id = a.ParentId
    )
select
  a.DirectChildId, sum(b.Amount) as Amount
from Recurse a
left join ItemValues b on a.Id = b.ItemId
group by
  DirectChildId;

وهناك طريقة غير CTE-يتطلب شكلا من أشكال التكرار، أو غير ذلك القائم على المؤشر. منذ انها بروك المخزنة على الاحتمال، وإذا كان هناك الكثير من البيانات للعنة من خلال، فإنه من المحتمل أن مقياس أفضل، طالما كنت شريحة البيانات بشكل مناسب.

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

إذا فهرس متفاوت المسافات بالفعل على ParentId بدلا من ذلك، إضافة فهرس غير متفاوت على الهوية. معا، وأنها ستكون يعادل تقريبا إلى ما سبق. لItemValues، قد ترغب في مؤشر على (ItemId) تحوى (المبلغ)، إذا كان الجدول الفعلي هو أوسع من ذلك.

نصائح أخرى

هل يمكنك تخزين البيانات الخاصة بك كما في نموذج مجموعة متداخلة (هنا هو الخلية <لأ href = "http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/" يختلط = "نوفولو noreferrer "> مرجع لكن الأفكار هي عامة عبر قواعد البيانات)؟ إذا كان الأمر كذلك فإن عمليات للعثور على قيمة كنت تبحث عن أن تكون بسيطة إلى حد ما.

هل هذا يجب أن يتم التعامل معها في قاعدة البيانات؟ أود أن أقترح جلب البيانات اللازمة إلى BLL وأداء العودية هناك.

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