ناقص (باستثناء) من 2 نفس الاستعلامات تُرجع نتائج غير فارغة

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

  •  25-07-2022
  •  | 
  •  

سؤال

لدي مشكلة مع SQL التالية. لماذا على الأرض ناقص 2 نفس الاستفسارات بالضبط ستعيد نتيجة غير فارغة؟ لقد جربت "Union All" بدلاً من الاتحاد ، لقد جربت أشياء أخرى كثيرة ، لم ينجح أي منها. يرجى تقديم النصيحة.

    SELECT y.segment1 po_num, fad.seq_num seq, fdst.short_text st
              FROM applsys.fnd_attached_documents fad,
                   applsys.fnd_documents fd,
                   applsys.fnd_documents_short_text fdst,
                   po_headers_all y
             WHERE     1 = 1
                   AND fad.pk1_value(+) = y.po_header_id
                   AND fad.entity_name = 'PO_HEADERS'
                   AND fad.document_id = fd.document_id
                   AND fd.datatype_id = 1
                   and fad.seq_num>=100
                   AND fdst.media_id = fd.media_id
                   and y.type_lookup_code='STANDARD'
                   AND NVL(y.CANCEL_FLAG,'N')='N'
                 --  and y.segment1 in (100,1000,100,650,26268)
                --   and y.segment1=1000
            UNION 
            SELECT poh.segment1, 1, '1' --null, null
              FROM    po.po_headers_all poh
                   LEFT JOIN
                      (SELECT fad1.pk1_value
                         FROM applsys.fnd_attached_documents fad1,
                              applsys.fnd_documents fd1
                        WHERE     1 = 1
                              AND fad1.entity_name = 'PO_HEADERS'
                              AND fad1.document_id = fd1.document_id
                              and fad1.seq_num>=100
                              AND fd1.datatype_id = 1) sub1
                   ON poh.po_header_id = sub1.pk1_value
             WHERE sub1.pk1_value IS NULL 
                        and poh.type_lookup_code='STANDARD'
                        AND NVL(poh.CANCEL_FLAG,'N')='N'
                      --  and poh.segment1 in (100,1000,100,650,26268) 
                      --  and poh.segment1=1000                       
          --   and poh.segment1=650)              
          minus
   SELECT y.segment1 po_num, fad.seq_num seq, fdst.short_text st
              FROM applsys.fnd_attached_documents fad,
                   applsys.fnd_documents fd,
                   applsys.fnd_documents_short_text fdst,
                   po_headers_all y
             WHERE     1 = 1
                   AND fad.pk1_value(+) = y.po_header_id
                   AND fad.entity_name = 'PO_HEADERS'
                   AND fad.document_id = fd.document_id
                   AND fd.datatype_id = 1
                   and fad.seq_num>=100
                   AND fdst.media_id = fd.media_id
                   and y.type_lookup_code='STANDARD'
                   AND NVL(y.CANCEL_FLAG,'N')='N'
                   --and y.segment1 in (100,1000,100,650,26268)
                   --and y.segment1=1000
            UNION 
            SELECT poh.segment1, 1, '1'--null,null
              FROM    po.po_headers_all poh
                   LEFT JOIN
                      (SELECT fad1.pk1_value
                         FROM applsys.fnd_attached_documents fad1,
                              applsys.fnd_documents fd1
                        WHERE     1 = 1
                              AND fad1.entity_name = 'PO_HEADERS'
                              AND fad1.document_id = fd1.document_id
                              and fad1.seq_num>=100
                              AND fd1.datatype_id = 1) sub1
                   ON poh.po_header_id = sub1.pk1_value
             WHERE sub1.pk1_value IS NULL 
                        and poh.type_lookup_code='STANDARD'
                        AND NVL(poh.CANCEL_FLAG,'N')='N'
                      --  and poh.segment1 in (100,1000,100,650,26268)
                      --  and poh.segment1=1000
                      --   and poh.segment1=650)
هل كانت مفيدة؟

المحلول

استخدم الأقواس. الآن ، أنت تفعل ((set1 UNION set2) MINUS set1) UNION set2 بينما كنت تقصد أن تفعل (set1 UNION set2) MINUS (set1 UNION set2).

بمعنى آخر ، أنت تقوم بتوحيد set1 و set2 ، وإزالة set1 من ذلك وتوحيد set2 مع ذلك ، بينما ربما كنت تهدف إلى أخذ اتحاد set1 و set2 وإزالة اتحاد set1 و set2 من ذلك. UNION و MINUS لها نفس الأسبقية ويتم معالجتها بالترتيب الذي واجهته.

نصائح أخرى

المشكلة هي أنه ، أولاً ، تقوم بعمل اتحاد من أول استفسارين ، ثم تقوم بعمل ناقص من الثالث ثم تقوم بالاتحاد للنتيجة مع الاستعلام الرابع.

لاحظ أن UNION [ALL] و MINUS لها نفس الأولوية. في الأساس ، إذا تجاهلنا التفاصيل ، فأنت تفعل:

SELECT query1
UNION
SELECT query2
MINUS
SELECT query1
UNION
SELECT query2

نظرًا لأن كل هذه العوامل المحددة لها نفس الأولوية ، فإنها تقيم واحدة تلو الأخرى.SELECT query1 MINUS SELECT query2 UNION SELECT query1 يجب أن تعود query2. ثم الأخير UNION يتم تطبيقه ، والنتيجة هي SELECT query2 UNION SELECT query2, ، وهو بالطبع query2.

لحل هذا ، يجب أن تفعل شيئًا كهذا:

SELECT * FROM (SELECT query1
               UNION
               SELECT query2)
MINUS
SELECT * FROM (SELECT query1
               UNION
               SELECT query2)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top