2个相同查询的减号(除外)返回非空结果集

时间:2013-11-07 10:21:08

标签: sql oracle except

我遇到以下SQL问题。为什么在地球上减去2个完全相同的查询会返回非空结果?我尝试过“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)

3 个答案:

答案 0 :(得分:2)

使用括号。现在,当您打算((set1 UNION set2) MINUS set1) UNION set2时,您正在进行(set1 UNION set2) MINUS (set1 UNION set2)

换句话说,你将set1和set2联合起来,从中删除set1并将set2与之结合,而你可能想要取一个set1和set2的并集,并从中删除set1和set2的并集。 UNIONMINUS具有相同的优先级,并按照遇到的顺序进行处理。

答案 1 :(得分:0)

问题在于,首先,你执行前两个查询的UNION,然后,你执行第三个的MINUS,然后使用第四个查询对结果进行UNION。

答案 2 :(得分: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)