2009-12-16 6 views
4

여러 테이블을 조인하고 많은 열을 반환하는 쿼리가 있습니다.Oracle : 다른 테이블에 행이 있는지 확인하십시오.

다른 테이블의 인덱스 된 열은 이러한 조인 된 테이블 중 하나의 PK를 참조합니다. 이제 새 테이블에 ID가있는 하나 이상의 행이 있는지 쿼리에 다른 열을 추가하고 싶습니다. 나는 이전 테이블

ID 
1 
2 
3 

및 새 테이블 중 하나가있는 경우

그럼

REF_ID 
1 
1 
1 
3 

나는

ID REF_EXISTS 
1   1 
2   0 
3   1 
나는 몇 가지 생각할 수

을 좀하고 싶습니다 그렇게하는 방법은 있지만 가장 우아하고 효율적인 것은 무엇입니까?


편집 내가 이전 테이블에서 50.000 기록와 함께 제공되는 쿼리의 성능을 테스트, 다른 모든 레코드가 새 테이블에 두 개의 행과 일치, 레코드 그래서 절반은 REF_EXISTS = 1 있습니다.

관심있는 사람들을 위해 평균 결과를 답변에 덧붙입니다. 모두에게 감사드립니다!

답변

7

또 다른 옵션 :

select O.ID 
    , case when N.ref_id is not null then 1 else 0 end as ref_exists 
from old_table o 
left outer join (select distinct ref_id from new_table) N 
    on O.id = N.ref_id 
+0

+1이 쿼리로 7 분이 지난 후 +1입니다. 이것은 하나의 group을 old_table에 조인하기 전에 ref_id를 멋지게 그룹화합니다. 나는 대신 네 표현식 대신 nvl2 (n.ref_id, 1,0)를 사용한다. –

+0

이것은 가장 빠른 쿼리 인 평균 테스트 시간 0.06 초입니다. 그리고 GROUP BY 필요 없음 :) –

1

사용 :

SELECT DISTINCT t1.id, 
      CASE WHEN t2.ref_id IS NULL THEN 0 ELSE 1 END AS REF_EXISTS 
    FROM TABLE_1 t1 
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id 

추가 DISTINCT 만의 고유 행이 표시되도록 할 수 있습니다.

+0

감사

안부, 업데이트 된 버전은 내 시험에서 약 0.17s했다. –

1

join은 예제 데이터에서 id=1의 경우처럼 하나의 ID에 대해 여러 행을 반환 할 수 있습니다. 다음과 같은 방법으로 그룹과 ID 당 하나 개의 행을 제한 할 수 있습니다

SELECT 
    t1.id 
, COUNT(DISTINCT t2.ref_id) as REF_EXISTS 
FROM TABLE_1 t1 
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id 
GROUP BY t1.id 

group by는 ID 당 하나의 행이 거기 보장합니다. 행이 발견되면 count(distinct t2.ref_id)은 1이되고 그렇지 않으면 0이됩니다.

편집 : 당신은 group by없이 다시 작성할 수 있습니다,하지만 난 그 일을 할 것입니다 의심 easer :

SELECT 
    t1.id 
, CASE WHEN EXISTS (
     SELECT * FROM TABLE_2 t2 WHERE t2.ref_id = t1.id) 
     THEN 1 ELSE 0 END as REF_EXISTS 
, .... 
FROM TABLE_1 t1 
+0

예, 이것이 가능합니다. 하지만 다른 열 30 개를 선택하고 있기 때문에이 그룹을 피하고 싶습니다. 다른 아이디어가 있습니까? –

+0

내 경험에 따르면 효율성을 높이기 위해 첫 번째 방법을 사용합니다. t2.ref_id에 색인이 있으면 oracle을 사용하는 것이 좋습니다. 선택한대로 EXPLAIN PLAN을 사용해야합니다. –

+0

맞습니다. 첫 번째 테스트가 내 테스트에서 더 효율적이었습니다 (0.20 초). t2.ref_id에 인덱스를 사용하지 않았으므로 동일한 성능 (다른 실행 계획)을 사용하는 힌트를 제공합니다. 두 번째 쿼리는 t2.ref_id (0.25s)에 인덱스가 필요한 유일한 것으로, 인덱스가없는 경우 약 3 분이 걸립니다. –

4

나는 것 :

select distinct ID, 
     case when exists (select 1 from REF_TABLE where ID_TABLE.ID = REF_TABLE.REF_ID) 
    then 1 else 0 end 
    from ID_TABLE 

PK와 FK에 색인이 있으면 표 스캔과 색인 조회가 필요합니다. K

+0

감사합니다. 시험에서 0.18 초를 보냈습니다. –

관련 문제