Проблема в том, что запрос на поиск CombinationId определенной комбинации кажется очень сложным.
Не должно быть слишком плохо. Если вы хотите, чтобы все комбинации содержали выбранные элементы (с допуском дополнительных элементов), это просто что-то вроде:
SELECT combinationID
FROM Combination
WHERE objectId IN (1, 3, 4)
GROUP BY combinationID
HAVING COUNT(*) = 3 -- The number of items in the combination
Если вам нужна только определенная комбинация (дополнительные предметы не допускаются), она может быть больше похожа на:
SELECT combinationID FROM (
-- ... query from above goes here, this gives us all with those 3
) AS candidates
-- This bit gives us a row for each item in the candidates, including
-- the items we know about but also any 'extras'
INNER JOIN combination ON (candidates.combinationID = combination.combinationID)
GROUP BY candidates.combinationID
HAVING COUNT(*) = 3 -- Because we joined back on ALL, ones with extras will have > 3
Вы также можете использовать NOT EXISTS здесь (или в исходном запросе), это, кажется, легче объяснить.
Наконец, вы также можете подумать и иметь один простой запрос
SELECT combinationID
FROM Combination AS candidates
INNER JOIN Combination AS allItems ON
(candidates.combinationID = allItems.combinationID)
WHERE candidates.objectId IN (1, 3, 4)
GROUP BY combinationID
HAVING COUNT(*) = 9 -- The number of items in the combination, squared
Другими словами, если мы ищем {1, 2}, и есть комбинация с {1, 2, 3}, мы получим результат {кандидатов, allItems} JOIN
из:
{1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {2, 3}
Дополнительные 3 дают COUNT(*)
, то есть 6 строк после GROUP
, а не 4, поэтому мы знаем, что это не та комбинация, которую мы ищем.