好的,经过多次尝试和编辑,这个解决方案最终有效了:
SELECT e1.EntityID, t1.TargetID
FROM Entities e1
JOIN Entities e2 ON (e1.EntityID = e2.EntityID)
CROSS JOIN Targets t1
LEFT OUTER JOIN Targets t2 ON (t1.TargetID = t2.TargetID
AND e2.AttributeName = t2.AttributeName
AND e2.AttributeValue = t2.AttributeValue)
GROUP BY e1.EntityID, t1.TargetID
HAVING COUNT(e2.AttributeValue) = COUNT(t2.AttributeValue);
测试数据:
INSERT INTO Entities VALUES
-- exact same attributes, should match
(1, Foo1 , 123 ),
(1, Bar1 , 123 ),
-- same attributes but different values, should not match
(2, Foo2 , 456 ),
(2, Bar2 , 456 ),
-- more columns in Entities, should not match
(3, Foo3 , 789 ),
(3, Bar3 , 789 ),
(3, Baz3 , 789 ),
-- fewer columns in Entities, should match
(4, Foo4 , 012 ),
(4, Bar4 , 012 ),
-- same as case 1, should match Target 1
(5, Foo1 , 123 ),
(5, Bar1 , 123 ),
-- one attribute with different value, should not match
(6, A , one ),
(6, B , two );
INSERT INTO Targets VALUES
(1, Foo1 , 123 ),
(1, Bar1 , 123 ),
(2, Foo2 , abc ),
(2, Bar2 , abc ),
(3, Foo3 , 789 ),
(3, Bar3 , 789 ),
(4, Foo4 , 012 ),
(4, Bar4 , 012 ),
(4, Baz4 , 012 ),
(6, A , one ),
(6, B , twox );
测试结果:
+----------+----------+
| EntityID | TargetID |
+----------+----------+
| 1 | 1 |
| 4 | 4 |
| 5 | 1 |
+----------+----------+
回应您的评论,这是一个表格颠倒的查询:
SELECT e1.EntityID, t1.TargetID
FROM Targets t1
JOIN Targets t2 ON (t1.TargetID = t2.TargetID)
CROSS JOIN Entities e1
LEFT OUTER JOIN Entities e2 ON (e1.EntityID = e2.EntityID
AND t2.AttributeName = e2.AttributeName
AND t2.AttributeValue = e2.AttributeValue)
GROUP BY e1.EntityID, t1.TargetID
HAVING COUNT(e2.AttributeValue) = COUNT(t2.AttributeValue);
这是给定上述相同输入数据的输出。
+----------+----------+
| EntityID | TargetID |
+----------+----------+
| 1 | 1 |
| 3 | 3 |
| 5 | 1 |
+----------+----------+