ربط جداول متعددة في SQL مع الحد من النتائج الأسية

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

  •  13-12-2019
  •  | 
  •  

سؤال

لقد بحثت في Google وStack Overflow للحصول على إجابة لاستعلامي، لكنني أشعر أن افتقاري إلى مفردات SQL يقف في طريقي للعثور على إجابة لأنني أعتقد أن هذا سيكون سؤالًا شائعًا.نرحب دائمًا بأي نقاط مفيدة في اتجاه ما أحتاج إلى قراءته.

بالنسبة للسؤال، أحاول الانضمام إلى ثلاثة جداول في Oracle 8i، على سبيل المثال، جدول الشركة وجدول الفاتورة وجدول الوظائف، ولا يوجد رابط بين جدول الفاتورة وجدول الوظائف.آمل أن أتمكن في استعلام واحد من ربط جميع الجداول الثلاثة التي تعرض جميع الفواتير وجميع الوظائف لشركة ما دون إرجاع جميع الوظائف لكل فاتورة (راجع نتائج الأمثلة الخاصة بي أدناه).

أريد أن أرى:

Company 1   Invoice 1   Job 1
Company 1   Invoice 2   Job 2
Company 1   Invoice 3   Job 3

لا أريد أن أرى:

Company 1   Invoice 1   Job 1
Company 1   Invoice 1   Job 2
Company 1   Invoice 1   Job 3
Company 1   Invoice 2   Job 1
Company 1   Invoice 2   Job 2
Company 1   Invoice 2   Job 3
Company 1   Invoice 3   Job 1
Company 1   Invoice 3   Job 2
Company 1   Invoice 3   Job 3

كما هو الحال دائمًا، شكرًا لك على أي مساعدة يمكنك تقديمها.

يحرر:

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

Company 1   Invoice 1   Job 1
Company 1   Invoice 2   Job 2
Company 1               Job 3

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

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

المحلول

الشرط الخاص بك يعني أن لديك مشكلة في المخطط الخاص بك.نصيحتي الأولى في هذه الحالة هي تعديل مخططك:أضف job_id ل invoice أو invoice_id ل job (أو جدول علاقة N-N invoice_job).

إذا لم تكن ترغب في تحديث مخططك، فيمكنك إجراء استعلام يؤدي إلى الانضمام.ال الاستعلام التالي سوف ينضم أساسا job و invoice واحد لواحد:

SELECT c.company_id, ij.job_id, ij.invoice_id
  FROM company c
  LEFT JOIN (SELECT job_id, invoice_id, 
                    NVL(j.company_id, i.company_id) company_id
               FROM (SELECT j.job_id, j.company_id,
                            row_number() OVER (PARTITION BY company_id
                                           ORDER BY job_id) job_no
                       FROM job j) j
               FULL OUTER JOIN 
                    (SELECT i.invoice_id, i.company_id,
                            row_number() OVER (PARTITION BY company_id
                                           ORDER BY invoice_id) invoice_no
                       FROM invoice i) i
                    ON j.company_id = i.company_id
                   AND j.job_no = i.invoice_no) ij
              ON c.company_id = ij.company_id

شرط الانضمام هنا مصطنع.إذا قمت بإزالة فاتورة، فقد تتغير علاقة الوظائف والفواتير.

إذا كان الجدولان غير مرتبطين بالفعل، فقد ترغب بدلاً من ذلك في عرض النتائج بشكل مختلف، على سبيل المثال:

SQL> SELECT cj.company_id, cj.jobs,
  2         listagg(i.invoice_id, ',')
  3            WITHIN GROUP (ORDER BY i.invoice_id) invoices
  4    FROM (SELECT c.company_id,
  5                 listagg(j.job_id, ',') WITHIN GROUP (ORDER BY job_id) jobs
  6            FROM company c LEFT JOIN job j ON c.company_id = j.company_id
  7           GROUP BY c.company_id) cj
  8    LEFT JOIN invoice i ON cj.company_id = i.company_id
  9  GROUP BY cj.company_id, cj.jobs;

COMPANY_ID  JOBS   INVOICES
----------- ------ --------
1           1,2,3  1,2
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top