T-SQL صفوف صف أكثر فعالية إلى العمود؟ crosstab لمسار XML ، المحور

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

سؤال

أنا أبحث عن الطريقة الأكثر أداء لتحويل الصفوف إلى أعمدة. لدي شرط لإخراج محتويات DB (وليس المخطط الفعلي أدناه ، ولكن المفهوم متشابه) في كل من التنسيقات الثابتة والتنسيقات المحددة. يمنحني الاستعلام أدناه لـ XML Path النتيجة التي أريدها ، ولكن عند التعامل مع أي شيء آخر غير الكميات الصغيرة من البيانات ، يمكن أن يستغرق وقتًا طويلاً.

 select orderid
   ,REPLACE((  SELECT '  ' + CAST(ProductId as varchar)
       FROM _details d
       WHERE d.OrderId = o.OrderId
       ORDER BY d.OrderId,d.DetailId
       FOR XML PATH('')
   ),' ','') as Products
 from _orders o

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

أود أن أشير أيضًا إلى أنني لست بحاجة إلى التعامل مع أسماء الأعمدة إما لأن إخراج صفوف الأطفال سيكون إما سلسلة عرض ثابت أو سلسلة محددة.

على سبيل المثال ، بالنظر إلى الجداول التالية:

OrderId     CustomerId
----------- -----------
1           1
2           2
3           3

DetailId    OrderId     ProductId
----------- ----------- -----------
1           1           100
2           1           158
3           1           234
4           2           125
5           3           101
6           3           105
7           3           212
8           3           250

للحصول على طلب أحتاج إلى الإخراج:

orderid     Products
----------- -----------------------
1             100  158  234
2             125
3             101  105  212  250

أو

orderid     Products
----------- -----------------------
1           100|158|234
2           125
3           101|105|212|250

أفكار أو اقتراحات؟ أنا أستخدم SQL Server 2K5.

مثال الإعداد:

   create table _orders (
  OrderId int identity(1,1) primary key nonclustered
  ,CustomerId int
 )

 create table _details (
  DetailId int identity(1,1) primary key nonclustered
  ,OrderId int 
  ,ProductId int
 )

 insert into _orders (CustomerId)
 select 1
 union select 2
 union select 3

 insert into _details (OrderId,ProductId)
 select 1,100
 union select 1,158
 union select 1,234
 union select 2,125
 union select 3,105
 union select 3,101
 union select 3,212
 union select 3,250

 CREATE CLUSTERED INDEX IX_CL__orders on _orders(OrderId)
 CREATE NONCLUSTERED INDEX IX_NCL__orders on _orders(OrderId)
 INCLUDE (CustomerId)

 CREATE CLUSTERED INDEX IX_CL_details on _details(OrderId)
 CREATE NONCLUSTERED INDEX IX_NCL_details on _details(OrderId)
 INCLUDE (DetailId,ProductId)

باستخدام مسار XML:

 select orderid
   ,REPLACE((  SELECT '  ' + CAST(ProductId as varchar)
       FROM _details d
       WHERE d.OrderId = o.OrderId
       ORDER BY d.OrderId,d.DetailId
       FOR XML PATH('')
   ),' ','') as Products
 from _orders o

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

orderid     Products
----------- -----------------------
1             100  158  234
2             125
3             101  105  212  250
هل كانت مفيدة؟

المحلول

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

لكن ال FOR XML PATH يعد البناء أفضل للقيم المتعددة للصفوف إلى عملية "محور" عمود أحادي السلسلة.

لست متأكدًا من سبب عدم أداءك جيدًا. ما هي الفهارس التي لديك على الجداول؟ كيف تبدو خطة التنفيذ الخاصة بك؟

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