2010-03-02 3 views
2

두 개의 테이블이 있다고 가정 해 보겠습니다. Person 및 Clothes 모두이 테이블에는 Person 및 의류 항목에 대한 속성을 저장하는 키/값 테이블이 있습니다 . 내가 찾으려는 의류의을 구체적으로 조각을 감안할 때내부 모든 "키/값"에 일치하는 두 테이블 조인 정확히 일치하는 쌍

ClothingID | AttributeKey | AttributeValue 
    99   'Age'   '20' 
    99   'Color'  'Blue' 
    60   'Age'   '20' 

:

PersonID | AttributeKey | AttributeValue 
    1   'Age'   '20' 
    1   'Size'   'Large' 
    2   'Age'   '20' 

A는 것처럼 보일 수 있습니다 속성에 의류의 버전에 가입 :

A는 것처럼 보일 수 있습니다 속성에 사람의 버전에 합류 모든 속성 쌍과 정확히 일치하는 Person 항목. 예를 들어, ClothingID 60의 경우, PersonID 1에는 일치하는 AGE가 있었지만 추가 속성이 있더라도 PersonID 2 만 가져 오려고합니다. 그리고 기본적으로 그 반대는 같은 효과가 있습니다.

주어진 의류 99 Person 속성에 Color 속성이 없으므로 아무런 결과가 없길 기대합니다.

INNER JOIN은 분명히 사람의 특정 속성과 일치하는 의복의 속성을 제공합니다. 하지만 가능한 모든 경기가 실제로 일치하는 행만 반환하고 여분이있는 경우 다른 행을 버리기를 원합니다. OUTER JOIN은 일치하는 것들에 대해 NULL 값을 줄 것이지만, 어떻게 발견하고 1 행에 NULL이 있으면 모든 Person 행을 버릴 수 있습니까? 이 같은

+0

당신이 당신의 테이블을 재구성하는 경우 속성이 저장되도록 자신의 분야에서 데이터를 쿼리 beco 더 쉽습니다. 예. 사람 (PersonID, 나이, 크기, 이름 등) 및 의복 (ClothingID, 나이, 색상, 유형, 설명 등) –

답변

2
SELECT * 
FROM persons p 
WHERE NOT EXISTS 
     (
     SELECT NULL 
     FROM (
       SELECT key, value 
       FROM clothing_attributes 
       WHERE clothing_id = 99 
       ) ca 
     FULL JOIN 
       (
       SELECT key, value 
       FROM person_attributes 
       WHERE person_id = p.id 
       ) pa 
     ON  ca.key = pa.key 
       AND ca.value = pa.value 
     WHERE ca.key IS NULL OR pa.key IS NULL 
     ) 
+0

의류는 아마도 사람 테이블에없는 추가 속성을 가질 수 있습니다. – Andomar

+0

@Andomar : 질문에 "주어진 의류 99 사람 속성에 색상 속성이 없으므로 아무런 결과도 기대하지 않습니다." – Quassnoi

+0

+1 ' 맞아, 완벽한 조인으로 좋은 솔루션 – Andomar

0

뭔가 :

SELECT p.*,c.* People p INNER JOIN Cloths c ON (P.key=c.key AND p.value=c.value) WHERE c.id=99

+0

나는 이것이 내가 원하는 것을 제공한다고 생각하지 않습니다. INNER JOIN (인너 죠인)은 나에게 사람과 옷이 일치하는 것을 알려줍니다. 양쪽에 속성이 많거나 적은 경우 결과 집합에 포함되지 않으며 일치하는 속성이됩니다. 모든 속성이 양면에 일치하지 않으면 행 중 원하는 것을 원하지 않습니다. – Vyrotek

1

당신은 모든 요구 사항이 충족되는지 확인하기 위해 하위 쿼리를 사용할 수 있습니다. PersonID와 ClothingID의 조합마다 inner join은 사람 테이블의 조건 수와 동일한 count(*)이어야합니다.

예 질의 :

select p.PersonID, c.ClothingID 
from @person p 
inner join @clothing c 
    on p.AttributeKey = c.AttributeKey 
    and p.AttributeValue = c.AttributeValue 
group by p.PersonID, c.ClothingID 
having count(*) = (
    select count(*) 
    from @person p2 
    where p.PersonID = p2.PersonID 
) 

가 출력 :

PersonID ClothingID 
2   60 
2   99 

데이터 쿼리를 테스트하는 데 사용 :

declare @person table (PersonID int, AttributeKey varchar(30), 
    AttributeValue varchar(30)) 
declare @clothing table (ClothingID int, AttributeKey varchar(30), 
    AttributeValue varchar(30)) 

insert into @person select 1, 'Age', '20' 
insert into @person select 1, 'Size', 'Large' 
insert into @person select 2, 'Age', '20' 

insert into @clothing select 99, 'Age', '20' 
insert into @clothing select 99, 'Color', 'Blue' 
insert into @clothing select 60, 'Age', '20' 
관련 문제