2010-03-02 35 views
2

假設我有兩個表 - 人員和衣服,並且這兩個表都具有關聯的鍵/值表,其存儲關於人員和衣物項目的屬性。內部基於完全匹​​配的所有「鍵/值」對加入兩個表

的接人的版本屬性可能看起來像:

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

的接服裝的版本屬性可能看起來像:

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

鑑於服裝specifc一塊,我想找到Person條目完全匹配所有的Attributes對。例如,給出ClothingID 60,即使PersonID 1確實具有匹配的AGE,但它具有額外的屬性,我也希望僅獲得PersonID 2。基本上相反也有同樣的效果。

鑑於服裝99我期望沒有結果,因爲沒有人的條目具有顏色屬性。

一個INNER JOIN顯然給了我匹配人的特定屬性的服裝屬性。但是我只想返回所有可能的匹配確實匹配的行,並且如果有額外的匹配則拋出其他行。一個OUTER JOIN會給我匹配NULL的值,但是如果我檢測到這個,並且拋出所有Person行,如果1行有NULLS?

+0

如果你調整你的表,這樣的屬性存儲在他們自己的領域中查詢數據消息更容易。例如。人(PersonID,年齡,大小,姓名等)和衣服(ClothingID,年齡,顏色,類型,說明等) – 2010-03-02 23:41:06

回答

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 2010-03-02 23:32:54

+0

@Andomar:問題說:「給定服裝99我期望沒有結果,因爲沒有人的條目有一個顏色屬性」 – Quassnoi 2010-03-02 23:34:11

+0

+1看起來像你'正確的,完全加入的完美解決方案 – Andomar 2010-03-02 23:46:55

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 2010-03-02 23:26:36

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' 
相關問題