2009-10-20 51 views
10

我有兩個選擇,我想以這種方式組合它們,只有兩個選擇中唯一的行才被返回。 Oracle 10g中是否有內置的方法來實現這一目標?Oracle的INTERSECT的對面

我知道我可以做這樣的事情:

 
(select1 UNION select2) 
MINUS 
(select1 INTERSECT select2) 

,但我想,以避免它。 select1select2都有20行,所以這種方式會很模糊,難以維護。

+1

該運營商的名稱是「對稱差」 - 這一點,谷歌給出了多項成果(至極都傾向於認爲這是不會要快)。 – AakashM 2009-10-20 07:56:14

+0

這對我來說不是問題,如果這很慢。這是我個人使用的批處理腳本,不需要它是超高效的。 – 2009-10-20 08:04:50

+0

這兩個選擇如何看起來像?可能會修改它們,以便只運行一個選擇並獲得最終結果。 – 2009-10-20 08:12:14

回答

8

如果同時select1select2回報沒有重複,你可以使用這樣的事情:

SELECT * FROM (select1 UNION ALL select2) a 
GROUP BY a.col1, a.col2, ... 
HAVING count(*) = 1 
1

這裏的另一個想法:

  • 做一個完全外部聯接選擇1和選擇2
  • 使用只有那些select1.id = NULL(記錄僅在select2中)或select2.ID = NULL(記錄僅在select1中)的記錄

這樣的:

SELECT * 
FROM select1 FULL OUTER JOIN select2 on select1.id = select2.id 
WHERE select1.id is null or select2.id is null 
0
-- get not intersect data 
SELECT_FINAL 
WHERE FIELD_PK IS NOT IN(
    -- get ids of intersect 
    SELECT_AUX FIELD_PK1 FROM (
     SELECT1 
     INTERSECT 
     SELECT2 
    ) 
) 

我做

1

這個工作對我 - 它是不知道有多快。

(select table_name from dba_tables where user = 'X' 
union 
select table_name from dba_tables where user = 'Y') 
minus 
(select table_name from dba_tables where user = 'X' 
intersect 
select table_name from dba_tables where user = 'Y') 
3

在Oracle 10g中,您可以使用Common Table Expressions。

WITH 
    select_1 AS (
    SELECT * 
    FROM your_table 
    WHERE your_condition = 1 
), 
    select_2 AS (
    SELECT * 
    FROM your_other_table 
    WHERE your_other_condition = 1 
) 
SELECT * FROM select_1 
UNION 
SELECT * FROM select_2 
MINUS 
(
    SELECT * FROM select_1 
    INTERSECT 
    SELECT * FROM select_2 
); 

這使您的子查詢可維護,您的最終查詢的目的清晰。

當然,有甲骨文添加SYM_DIFFERENCE運營商SQL甚至會更好,但我不屏住呼吸—他們還是不相信一個BOOLEAN數據類型將是一個不錯的主意。

0

這是另一種解決方案,這次使用count()分析(Oracle 10或更高版本)。

優點:

  • 我們可以指定(在本例中例如KK1,KK2)上EXTRASECT哪些列。
  • 我們可以選擇我們不需要匹配的非關鍵列(例如NK1,NK2 ...)。
  • 高效計劃。
  • 與FULL OUTER JOIN示例類似,但我們沒有將關鍵列作爲需要解碼的獨立字段或將它們摺疊在一起的大小寫。

select KK1, KK2, NK1, NK2 from (select KK1, KK2, NK1, NK2, count(*) over(partition by KK1, KK2) cnt from (select KK1, KK2, NK1, NK2 from X union all select KK1, KK2, NK1, NK2 from Y)) where cnt = 1;