2016-09-26 93 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