2013-11-07 3 views
1

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

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) 

ответ

2

Используйте круглые скобки. Прямо сейчас, вы делаете ((set1 UNION set2) MINUS set1) UNION set2, пока вы хотели сделать (set1 UNION set2) MINUS (set1 UNION set2).

Другими словами, вы объединяете set1 и set2, удаляя из него set1 и объединяете set2 с этим, в то время как вы, вероятно, должны были принять объединение set1 и set2 и удалить из него объединение set1 и set2. UNION и MINUS имеют одинаковый приоритет и обрабатываются в том порядке, в котором они встречаются.

0

Проблема в том, что, во-первых, вы выполняете UNION первых двух запросов, затем вы делаете MINUS третьего, а затем вы UNION результат с четвертым запросом.

0

Отметьте, что 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)