Вынуждены угадать схему и предположить, что клиент может заказать один и тот же продукт несколько раз, вы можете использовать что-то вроде этого...
WITH
Products (
productID,
inclusive
)
AS
(
SELECT 'P1', 1
UNION ALL SELECT 'P2', 1
UNION ALL SELECT 'P3', 0
)
SELECT
customerID
FROM
Orders
INNER JOIN
Products
ON Orders.ProductID = Products.ProductID
GROUP BY
customerID
HAVING
COUNT(distinct Orders.ProductID) = (SELECT SUM(inclusive) FROM Products)
AND MIN(Products.inclusive) = 1
Во-первых, соединение отфильтровывает все, что принадлежит только Заказам, включая ЛЮБОЙ из P1
, P2
или P3
.
GROUP BY объединяет их в группы заказов, по одной группе для каждого клиента.
Первое предложение HAVING просматривает все заказы в этом списке. Он подсчитывает количество разных товаров в этом подмножестве. Он проверяет количество инклюзивных продуктов в списке продуктов, который мы ищем. Он предусматривает, что эти две цифры должны быть одинаковыми.
[В этом примере; они должны были заказать ровно два разных продукта.]
Второе предложение HAVING проверяет, имеет ли какой-либо из этих продуктов inclusive = 0
.
[Ни один продукт, заказанный покупателем, не может отображаться в списке исключений.]
EDIT: Это альтернатива, которую некоторые люди предпочитают, но я думаю, что она менее эффективна (в случаях, когда таблица Orders имеет значительный размер).
SELECT
customerID
FROM
Orders
WHERE
ProductID in ('P1', 'P2')
GROUP BY
customerID
HAVING
COUNT(distinct ProductID) = 2
AND NOT EXISTS (SELECT *
FROM Orders AS lookup
WHERE CustomerID = Orders.CustomerID
AND ProductID IN ('P3')
)
person
MatBailie
schedule
13.04.2012