假设我有两个表 - Person和Clothes,这两个表都有关联的Key / Value表,用于存储有关Person和服装项的属性。
Person to Attributes的加入版本可能如下所示:
PersonID | AttributeKey | AttributeValue
1 'Age' '20'
1 'Size' 'Large'
2 'Age' '20'
服装到属性的连接版本可能如下所示:
ClothingID | AttributeKey | AttributeValue
99 'Age' '20'
99 'Color' 'Blue'
60 'Age' '20'
给定一件特定的衣服,我想找到与所有属性对完全匹配的Person条目。例如,给定ClothingID 60,我想获得PersonID 2,即使PersonID 1确实具有匹配的AGE,但它具有额外的属性。而基本上相反的效果也是如此。
给定服装99我会期望没有结果,因为没有Person条目具有Color属性。
INNER JOIN显然给了我符合人物特定属性的服装属性。但我想只返回所有可能的匹配确实匹配的行,如果有额外的则抛出其他行。一个OUTER JOIN会给我一些匹配的NULL值但我如何检测到这个并抛出所有Person行,如果有一行有NULLS?
答案 0 :(得分: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
)
答案 1 :(得分: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'
答案 2 :(得分:0)
这样的事情:
SELECT p.*,c.* People p INNER JOIN Cloths c ON (P.key=c.key AND p.value=c.value) WHERE c.id=99