Минус (кроме) из 2 тех же запросов возвращает непустые результаты

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

  •  25-07-2022
  •  | 
  •  

Вопрос

У меня есть проблема со следующим SQL. Почему на земле минус 2 одинаковых запросов вернет непустые результаты? Я попробовал «Союз все» вместо Союза, я пробовал много других вещей, ни одно из которых не работало. Пожалуйста, порекомендуйте.

    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