2009-10-20 3 views
10

두 개의 선택이 있고 두 개의 고유 한 행만 리턴되는 방식으로 결합하려고합니다. Oracle 10g에서 내장 된 방법으로이를 수행 할 수 있습니까?오라클의 INTERSECT의 반대

 
(select1 UNION select2) 
MINUS 
(select1 INTERSECT select2) 

하지만 난 그것을 피하기 위해 싶습니다

은 내가 이런 식으로 뭔가를 할 수있어. select1select2 모두 20 개의 라인을 가지고 있기 때문에이 방법은 유지하기가 매우 어렵고 어렵습니다. 모두 select1select2 복귀에는 중복,이 같은 것을 사용하지 않으면

+1

이 연산자의 이름은 '대칭 차이'입니다 -이와 함께, 구글은 검색 결과의 수 (모든이 빨리 될 수 없습니다 제안하는 경향이 이십 기가 바이트)를 제공합니다. – AakashM

+0

느린 경우 문제가되지 않습니다.이것은 나의 개인적인 사용을위한 배치 스크립트이며, 그것을 효율적으로 사용할 필요가 없습니다. –

+0

두 선택은 어떻게 생겼습니까? 그것들을 수정할 수 있기 때문에 하나의 select 만 실행하고 최종 결과를 얻을 수 있습니다. –

답변

8

: 여기

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

이것은 그것이 확실하지 얼마나 빨리 me-를 위해 일하지.

(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에는 공통 테이블 표현식이 있습니다.

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 
); 

이렇게하면 하위 쿼리를 유지 관리 할 수 ​​있고 최종 쿼리의 목적을 명확하게 유지할 수 있습니다. SQL이 더 나은 것에 오라클은 SYM_DIFFERENCE 연산자를 추가 할 수 있지만 나는 그들이 여전히 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;