2016-08-25 5 views
1

의이 적어도 1 조건이 충족되는 여러 테이블에 가입

내가 판매 된 항목을 나열 할 필요가 Area_ID, 내가 ITEM_ID, Organisation_ID, Salesman_ID을 포함 판매와 기본 테이블 'Z'를 가지고 있다고 가정 해 봅시다 테이블 A의 영업 사원 또는 테이블 B의 조직 또는 테이블 C의 지역의 영업 사원 중 하나가 선택합니다. 영역, 조직 및 영업 사원은 서로 독립적입니다.

나는 WHERE 절에 부속 선택을 사용하여 쿼리 만들 수 있었다 :

Select Z.Item_ID From Z WHERE 
Z.Salesman_ID IN (SELECT Salesman_ID From A) OR 
Z.Organisation_ID IN (SELECT Organisation_ID From B) OR 
Z.Area_ID IN (SELECT Area_ID From C) 

는 그러나,의 performace이 문제가, 그리고 나는 빨리 부속 선택보다 조인 들었다. "OR"의 결과를 얻을 수있는 방식으로 조인을 결합하는 것에 대해 내 마음을 감쌀 수는 없습니다 ...

Sidenote : 게시하기 전에 SQL 결합의 시각적 설명을 읽고 답변을 찾으려고 시도했습니다. 구글을 통해 내 질문 (그것은 매우 일반적인 키워드를 기반으로 정답을 찾을 까다로운, tho).

샘플

A  | B  | C 
S04 | O16 | A07 
S12 | O01 | A08 
S14 |  | 
S15 |  | 

Z 테이블 :

I01 S09 O12 A14 
I02 S17 O20 A17 
I03 S18 O20 A12 
I04 S07 O15 A01 
I05 S14 O03 A08 
I06 S16 O18 A20 
I07 S05 O03 A12 
I08 S11 O14 A05 
I09 S15 O19 A10 
I10 S13 O07 A18 
I11 S15 O08 A03 
I12 S15 O14 A13 
I13 S08 O16 A18 
I14 S16 O19 A14 
I15 S13 O18 A10 
I16 S03 O12 A08 
I17 S11 O09 A16 
I18 S14 O17 A13 
I19 S02 O13 A11 
I20 S18 O10 A06 
I21 S10 O05 A15 
I22 S19 O20 A06 
I23 S15 O16 A20 
I24 S02 O07 A04 

예상 결과 : 대부분의 성능 관련 질문과 마찬가지로

I05 
I09 
I11 
I12 
I13 
I16 
I18 
I23 
+1

수는 샘플 데이터를 표시 하시겠습니까? 귀하의 질문에서 "OR"가 의미하는 바를 명확하게 해줍니다. –

답변

0

, 그것은 당신의 테이블 스키마에 조금 따라, 인덱스, 데이터 등. 그 말로는, 종종 번 existsouter joins 더 efficien 수 있습니다 t :

를 사용해서 언급하는 동등한 join 접근해야한다 :

select z.item_id 
from z 
    left join a on z.salesman_id = a.salesman_id 
    left join b on z.organisation_id = b.organisation_id 
    left join c on z.area_id = c.area_id 
where a.salesman_id is not null or 
    b.organisation_id is not null or 
    c.area_id is not null 

데이터에 따라이와 distinct을 사용해야 할 수도 있습니다.


편집 : 당신의 Id 필드는 개체마다 고유 경우 샘플 데이터로, 다음 existsunion all를 사용하는이 솔루션은 아마 (z.salesman_id, z.organisation_id, z.area_id)에 인덱스와 가장 효율적입니다 :

select item_id 
from z 
where exists (
    select 1 
    from ( 
     select salesman_id id from a union all 
     select organisation_id from b union all 
     select area_id from c 
    ) t 
    where t.id in (z.salesman_id, z.organisation_id, z.area_id) 
) 
+1

안타깝게도 실제 데이터베이스 ID 필드는 엔티티마다 고유하지 않습니다 (각각 숫자 만이므로 Salesman 1, 조직 1 및 영역 1이 있으므로 연합 접근 방식이 작동하지 않습니다). –

+0

왼쪽 가입이 가능합니다! 그리고 나는이 방법이 NULL이 아니라 트릭을 사용할 수 있다는 것을 깨닫지 못했습니다 :) –

관련 문제