1

我对以下 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)
4

3 回答 3

2

使用括号。现在,你正在做((set1 UNION set2) MINUS set1) UNION set2你想做的事情(set1 UNION set2) MINUS (set1 UNION set2)

换句话说,您将 set1 和 set2 合并,从中删除 set1 并将 set2 与之合并,而您可能打算采用 set1 和 set2 的并集并从中删除 set1 和 set2 的并集。UNIONMINUS具有相同的优先级并按照遇到的顺序进行处理。

于 2013-11-07T10:27:40.463 回答
0

问题是,首先,您对前两个查询进行 UNION,然后对第三个查询进行 MINUS,然后将结果与第四个查询进行 UNION。

于 2013-11-07T10:28:05.570 回答
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)
于 2013-11-07T10:28:11.673 回答