2016-09-26 57 views
1

可以说我有一个多对多的关系:SQL - 匹配的一组记录

Profile <- Profile_Attribute -> Attribute 
-------  -----------------  --------- 
ProfileID Profile_AttributeID AttributeID 
Name   ProfileID    Name 
      AttributeID 
      Value 

纵观数据,配置文件有2个属性,属性A和B.属性我想找到任何配置文件记录具有所有具有匹配值的属性,而无需对属性ID /名称进行硬编码。所以基本上我想将表传递给包含属性的查询,并且它会查找匹配的任何配置文件记录。配置文件记录将只匹配如果确切的属性是相同的,即。它不能具有更多的属性,对具有不同值的属性的属性更少。

这是我想出的SQL。只是想知道是否有更好的方法来做到这一点。

--Declare the set of attributes/values that I want to find matching profiles for 
DECLARE @tblCheck TABLE 
(
    AttributeID INT, 
    Value VARCHAR(255) 
) 

--We're looking for any profile record that has an attribute 2 of abc and 
--an attribute 1 of xyz, but nothing else 
INSERT INTO @tblCheck (AttributeID, Value) VALUES (2, 'abc') 
INSERT INTO @tblCheck (AttributeID, Value) VALUES (1, 'xyz') 

--Find all profiles that have the same attributes and the same values 
SELECT 
    p.ProfileID, 
    COUNT(*) 
FROM 
    [Profile] p 
JOIN 
    [Profile_attribute] pa ON pa.ProfileID = p.ProfileID 
LEFT JOIN 
    @tblCheck c ON pa.AttributeID = c.AttributeID AND 
        --Match on exact value or a wildcard 
        (pa.Value = c.Value OR pa.Value = '*') 
GROUP BY 
    p.ProfileID 
HAVING 
    COUNT(*) = (SELECT COUNT(*) FROM @tblCheck) 
+0

样品和预期的数据可能会更好。 – NEER

+0

为什么使用左外连接而不是使用@tblCheck进行内连接? – Beth

+0

是的,很好的电话,我不知道为什么我这样做! :) – Jeremy

回答

1

我认为你只是希望这样的事情:

select c.ProfileId, Count(*) from @tblCheck as a 
inner join Profile_attribute as b on a.AttributeID = b.AttributeID and a.Value = b.Value 
inner join Profile as c on c.ProfileID = b.ProfileID 
Group by c.ProfileID