"تمحور" جدول في SQL (أيالجدولة المتقاطعة / الجدولة المتقاطعة)

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

  •  03-07-2019
  •  | 
  •  

سؤال

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

Campaign
----------
CampaignID

Source
-----------------------
Source_ID | Campaign_ID

Content
---------------------------------------------------------
Content_ID | Campaign_ID | Content_Row_ID | Content_Value

التقرير يجب أن يقرأ هكذا:

CampaignID - SourceID - ContentRowID(Value(A)) - ContentRowID(Value(B))

حيث يعني ContentRowID(Value(A)) "ابحث عن صف يحتوي على معرف حملة محدد وContentRowId لـ "A" ثم احصل على ContentValue لهذا الصف"

في الأساس، لا بد لي من "تحويل" (أعتقد أن هذا هو المصطلح الصحيح) الصفوف إلى أعمدة ...

إنها قاعدة بيانات Oracle 10g...

أي اقتراحات؟

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

المحلول

وهذا هو أول طعنة لي في ذلك. الصقل تأتي مرة واحدة معرفة المزيد عن محتويات الجدول المحتوى.

أولا، تحتاج جدول مؤقت:

CREATE TABLE pivot (count integer);
INSERT INTO pivot VALUES (1);
INSERT INTO pivot VALUES (2);

والآن نحن على استعداد للاستعلام.

SELECT campaignid, sourceid, a.contentvalue, b.contentvalue
FROM content a, content b, pivot, source
WHERE source.campaignid = content.campaignid
AND pivot = 1 AND a.contentrowid = 'A'
AND pivot = 2 AND b.contentrowid = 'B'

نصائح أخرى

ذكر بيل كاروين هذا، ولكن أعتقد أن هذا يستحق الإشارة إليه بوضوح شديد:

SQL لا تفعل ما تطلبه، لذا فإن أي "حل" تحصل عليه سيكون بمثابة خدعة.

اذا أنت يعرف, من المؤكد أنه سيتم تشغيله دائمًا على Oracle 10، ومن المؤكد أن جدولة والتر ميتي قد تفعل ذلك.الطريقة الصحيحة للقيام بذلك هي العمل على أسهل مجموعة من ترتيب الفرز في الاستعلام ورمز التطبيق لوضعها بشكل صحيح.

  • يعمل على أنظمة قواعد البيانات الأخرى،
  • لا يخاطر بانهيار أي طبقات أخرى (أتذكر أن MySQL تواجه مشكلة مع أكثر من 255 عمودًا على سبيل المثال.هل انت متأكد انك مكتبة الواجهة تتواءم وكذلك ديسيبل نفسها؟)
  • إنه (عادة) ليس أصعب بكثير.

إذا كنت بحاجة إلى ذلك، يمكنك فقط أن تطلب Content_Row_IDأولاً، ثم اطلب أي صفوف تحتاجها، مرتبة حسب CampaignID, ContentRowID, ، والذي سيعطيك كل خلية (مأهولة) بترتيب من اليسار إلى اليمين، سطرًا بسطر.


ملاحظة.

هناك مجموعة من الأشياء التي يعتقد الإنسان المعاصر أن SQL يجب أن تمتلكها/تفعلها ولكنها غير موجودة.هذا أحد النطاقات المولدة، وهو إغلاق عودي، حدودي آخر ORDER BY, ، لغة برمجة موحدة...والقائمة تطول.(على الرغم من أنه من المسلم به أن هناك خدعة لـ ORDER BY)

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

SELECT CampaignID, SourceID, 
   (SELECT Content_Value FROM Content c 
      WHERE c.Campaign_ID=s.Campaign_ID 
      AND Content_Row_ID = 39100 
      AND rownum<=1) AS Value39100,
   (SELECT Content_Value FROM Content c 
      WHERE c.Campaign_ID=s.Campaign_ID 
      AND Content_Row_ID = 39200 
      AND rownum<=1) AS Value39200
FROM Source s;

وكرر فرعي لكل Content_Row_ID الاضافيه.

لقيام بذلك في SQL القياسية، وكنت بحاجة لمعرفة كل القيم متميزة من Content_Row_ID، والقيام الانضمام في قيمة مميزة. ثم كنت في حاجة الى عمود في قيمة متميزة من Content_Row_ID.

SELECT CA.Campaign_ID, 
  C1.Content_Value AS "39100",
  C2.Content_Value AS "39200",
  C3.Content_Value AS "39300"
FROM Campaign CA
  LEFT OUTER JOIN Content C1 ON (CA.Campaign_ID = C1.Campaign_ID 
    AND C1.Content_Row_ID = 39100)
  LEFT OUTER JOIN Content C2 ON (CA.Campaign_ID = C2.Campaign_ID 
    AND C2.Content_Row_ID = 39200)
  LEFT OUTER JOIN Content C3 ON (CA.Campaign_ID = C3.Campaign_ID 
    AND C3.Content_Row_ID = 39300);

ولما كان عدد من قيم مميزة ينمو أكبر، ويصبح هذا الاستعلام مكلفة للغاية لتشغيل بكفاءة. هو على الأرجح أسهل لجلب المزيد من البيانات ببساطة وإعادة في PL / SQL أو في رمز التطبيق.

وبيل Karwin واندرس Eurenius هي الصحيحة أنه لا يوجد حل غير واضحة، وليس هناك أي حل على الإطلاق عندما يكون عدد الناتجة قيم العمود ليست معروفة مسبقا. أوراكل 11g يفعل تبسيط إلى حد ما مع <لأ href = "http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-pivot.html" يختلط = "نوفولو noreferrer" > المشغل PIVOT ، ولكن الأعمدة لا يزال يتعين معروفة مسبقا والتي لا تفي بالمعايير 10G لسؤالك.

إذا كنت تحتاج إلى عدد ديناميكية من الأعمدة، وأنا لا أعتقد أن هذا يمكن أن يتم في SQL القياسية التي، للأسف، يتجاوز حد علمي. ولكن هناك ملامح أوراكل التي يمكن أن تفعل ذلك. لقد وجدت بعض الموارد:

http://www.sqlsnippets.com/en/topic-12200.html

HTTP: //asktom.oracle.com/pls/asktom/f؟p=100:11:0::::P11_QUESTION_ID:124812348063#41097616566309

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

مصطلح آخر لـ "تحريك الجدول" هو الجدولة الترافقية.

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

عند هذه النقطة، يمكنك تشغيل "معالج الاستعلام"، ومطالبته بإنشاء استعلام جدولي لك.إنها حقًا سهلة مثل الإجابة على الأسئلة التي يطرحها عليك المعالج.الجانب المؤسف لهذا الحل هو أنه إذا نظرت إلى الاستعلام الناتج في عرض SQL، فسترى بعض SQL الخاصة بلهجة Access الخاصة بـ SQL، ولا يمكن استخدامها بشكل عام عبر الأنظمة الأساسية الأخرى.

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

مرة أخرى، إذا كنت تريد حقًا القيام بذلك في SQL، فمن المفترض أن يساعدك "Oracle، المرجع الكامل".

إذا كنت لا تعرف عدد الأعمدة في خط الهجوم فقط اعادة استعلام SQL العادي واستخدام رمز جانب الملقم مثل I المذكورة هنا: <لأ href = "https://stackoverflow.com/questions/333181/a -question-حول-datagrid و-SQL الاستعلام "> تعبئة Datagrid و SQL سؤال

ولقد فعلت ذلك لحل مع هذا SQL. أنا بحاجة إلى أن صفوف يكون عدد الصفوف والأعمدة يكون sumary كل CLASSE خلال الشهر، لذلك، العمود الأول هو sumary الصف وكل OHTERS الأعمدة هي sumary من كل شهر، والصف الأخير هو sumary عمود كامل شهرا بعد شهر.

وحظا سعيدا

Select DS.Cla,
Sum(case
when (Extract(year from DS.Data) =:intYear) then DS.PRE
else 0
end) as ToTal,
Sum(case
when (Extract(month from DS.Data) =1) then DS.PRE
else 0
end) as Jan,
Sum(case
when (Extract(month from DS.Data) =2) then DS.PRE
else 0
end) as FEV,
Sum(case
when (Extract(month from DS.Data) =3) then DS.PRE
else 0
end) as MAR,
Sum(case
when (Extract(month from DS.Data) =4) then DS.PRE
else 0
end) as ABR,
Sum(case
when (Extract(month from DS.Data) =5) then DS.PRE
else 0
end) as MAI,
Sum(case
when (Extract(month from DS.Data) =6) then DS.PRE
else 0
end) as JUN,
Sum(case
when (Extract(month from DS.Data) =7) then DS.PRE
else 0
end) as JUL,
Sum(case
when (Extract(month from DS.Data) =8) then DS.PRE
else 0
end) as AGO,
Sum(case
when (Extract(month from DS.Data) =9) then DS.PRE
else 0
end) as SETE,
Sum(case
when (Extract(month from DS.Data) =10) then DS.PRE
else 0
end) as OUT,
Sum(case
when (Extract(month from DS.Data) =11) then DS.PRE
else 0
end) as NOV,
Sum(case
when (Extract(month from DS.Data) =12) then DS.PRE
else 0
end) as DEZ
from Dados DS
Where DS.Cla > 0
And Extract(Year from DS.Data) = :intYear
group by DS.CLA

Union All

Select 0*count(DS.cla),  0*count(DS.cla),
Sum(case
when (Extract(month from DS.Data) =1) then DS.PRE
else 0
end) as JAN,
Sum(case
when (Extract(month from DS.Data) =2) then DS.PRE
else 0
end) as FEV,
Sum(case
when (Extract(month from DS.Data) =3) then DS.PRE
else 0
end) as MAR,
Sum(case
when (Extract(month from DS.Data) =4) then DS.PRE
else 0
end) as ABR,
Sum(case
when (Extract(month from DS.Data) =5) then DS.PRE
else 0
end) as MAI,
Sum(case
when (Extract(month from DS.Data) =6) then DS.PRE
else 0
end) as JUN,
Sum(case
when (Extract(month from DS.Data) =7) then DS.PRE
else 0
end) as JUL,
Sum(case
when (Extract(month from DS.Data) =8) then DS.PRE
else 0
end) as AGO,
Sum(case
when (Extract(month from DS.Data) =9) then DS.PRE
else 0
end) as SETE,
Sum(case
when (Extract(month from DS.Data) =10) then DS.PRE
else 0
end) as OUT,
Sum(case
when (Extract(month from DS.Data) =11) then DS.PRE
else 0
end) as NOV,
Sum(case
when (Extract(month from DS.Data) =12) then DS.PRE
else 0
end) as DEZ
from Dados DS
Where DS.Cla > 0
And Extract(Year from DS.Data) = :intYear
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top