さて、いくつかの試行と編集の後、このソリューションは最終的に機能すると思います:
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 |
+----------+----------+