SELECT transactions.*
WHERE (SELECT count(*)
FROM items_transactions
WHERE items_transactions.transaction_id = transactions.transaction_id
AND items_transactions.item_id IN (<list of items>)
) = <number of items>
Хотя это, вероятно, выполнит сканирование транзакций, вложив коррелированный подзапрос для каждого ... не особенно эффективно, поэтому, возможно:
SELECT transactions.*
WHERE EXISTS (SELECT 1 FROM items_transactions
WHERE items_transactions.transaction_id = transactions.transaction_id
AND items_transactions.item_id IN (<list of items>)
)
AND
(SELECT count(*)
FROM items_transactions
WHERE items_transactions.transaction_id = transactions.transaction_id
AND items_transactions.item_id IN (<list of items>)
) = <number of items>
или что-то подобное, чтобы убедить БД сначала найти транзакции, связанные по крайней мере с одним из элементов, а затем проверить, что каждая транзакция связана со всеми элементами позже.
Как кто-то заметил, вы также можете просто сгенерировать предложения соединения для каждого элемента, что может быть лучше, если количество элементов невелико.