我遇到以下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)
答案 0 :(得分: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
具有相同的优先级,并按照遇到的顺序进行处理。
答案 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)