2011-12-30 3 views
4

에 보관 관계를 비교 내가 5 표, A, AZ, Z, BZ, BSQL은 여러 테이블 연결

(난이 질문을 설명하는 힘든 시간을 보내고 있습니다).

AZAZ 사이의 다 대다 관계를 나타냅니다. BZBZ 사이의 다 대다 관계를 나타냅니다.

결과 집합은 A B이고 BAZ 풀 세트에 연결됩니다.

Tag1 
Tag2 
Tag3 

A는 개체 테이블이며, 포함 :

ObjectA 
ObjectB 
ObjectC 

B이 위젯 표이며이 포함

자, Z이 태그 테이블 및 포함 가정 해 봅시다

WidgetX 
WidgetY 
WidgetZ 

AZ co ntains :

ObjectA Tag1 
ObjectA Tag2 
ObjectB Tag3 
ObjectC Tag2 
ObjectC Tag3 

BZ 포함은 :

WidgetX Tag1 
WidgetX Tag2 
WidgetY Tag2 
WidgetY Tag3 
WidgetZ Tag3 

내 결과로 설정하려는 :

ObjectA WidgetX 
ObjectB WidgetY 
ObjectB WidgetZ 
ObjectC WidgetY 

쿼리에서이 행할, 또는 내가 다시 일부 중간 세트를 당겨해야 데이터를 반복하고 코드를 반복합니까?

답변

3

좋아요, 주요 수정 사항은 의견을 바탕으로 수정되었습니다. 그것은 약간의 미봉책하지만 여기 당신은 간다 : 그것은 바로 수를 얻기 위해 불쾌한 하위 쿼리를 사용

select distinct 
    x.aid, 
    x.bid 
from 
    (select 
     az.aid, 
     bz.bid, 
     (select COUNT(1) from az az1 where az1.aid = az.aid) as acount, 
     (select COUNT(1) from bz bz1 where bz1.zid in (select zid from az az1 where az1.aid = az.aid) and bz1.bid = bz.bid) as bcount 
    from 
     az 
     inner join bz on 
      az.zid = bz.zid 
    ) x 
where 
    x.acount = x.bcount 

, 다음 기준에 따라 우리의 행 집합을 제한합니다.

+0

올바른 결과 집합이 아닙니다. ObjectA는 Tag1 및 Tag2에 연결됩니다. WidgetY는 Tag1에 연결되어 있지 않으므로 WidgetY에 대한 ObjectA는 유효하지 않습니다. –

+0

@JacobG - 장래에 더 나은 테이블 이름과 실제 데이터를 사용하려고하면이 예제가 더 어려워집니다. – JonH

+0

@JacobG - 알겠습니다. 올바른 것으로 수정되었습니다 ... 그게 효과가 있는지 알려주세요. – Eric

3

주요 편집 : 안드리 바르게 지적한대로

, 내가 처음으로 이동 스틱의 잘못된 말을했다.

select a, b.b 
from az cross join b 
left outer join bz on az.z = bz.z and b.b = bz.b 
group by a, b.b 
having sum(case when bz.b is null then 1 else 0 end) = 0 

크로스 조인은 모든 b가 AZ의 모든 a에 대한 조건을 만족한다는 가정을 표현하는 테이블을 설정합니다. 왼쪽 외부 조인은이 가정을 검사하고 해당 가정이 실패한 bz.b 열에 null 값을 남겨 둡니다. having 절은 이러한 null을 하나 이상 포함하는 a-b 쌍을 제외합니다.

+0

질문을 이해하는 방법에서, 객체의 세트는 객체가 위젯과 일치하도록 위젯의 하위 세트 여야합니다. 검색어가 너무 많은 일치를 반환합니다. –

+1

+1, 나는 어제의 줄을 따라 무언가를 졸랐다. 단지'b '보다는'b (b)에서 b를 선택하십시오'에 교차 결합을 생각하고 있었지만 결과에 영향을 미치지 않으며 효율성이 떨어질 수도 있습니다. –

+0

+1이 하나도 작동합니다. 그것은 에릭의 솔루션보다 훨씬 느리다. 나와 함께 노는 좋은 전략. 감사! –