它位于 SQL Server 2008 R2 中。
我们有 3 种产品,订单和客户:P1 P2 P3
我们想知道订购 P1 和 P2 但不订购 P3 的客户。我们不希望得到订购所有 3 种产品的客户。我不知道如何编写该查询。你能告诉我吗?谢谢。
我们只有 2 张桌子。订单和客户。产品名称是固定的。
它位于 SQL Server 2008 R2 中。
我们有 3 种产品,订单和客户:P1 P2 P3
我们想知道订购 P1 和 P2 但不订购 P3 的客户。我们不希望得到订购所有 3 种产品的客户。我不知道如何编写该查询。你能告诉我吗?谢谢。
我们只有 2 张桌子。订单和客户。产品名称是固定的。
被迫猜测架构,并假设客户可以多次订购相同的产品,您可以使用这样的东西......
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
.
[客户订购的产品不得出现在排除列表中。]
编辑:这是另一种选择,有些人似乎更喜欢,但我认为它的性能较低(在 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')
)
假设 Orders 包含 customerID 和 ProductId 列
select disrinct(customerID) from Orders
为您提供所有下订单的客户
select customerID, COUNT(distinct(productID))
from Orders
where productID in ('P1', 'P2')
and customerid not in (select customerID
from Orders
where productID in ('P3'))
group by customerID
having COUNT(distinct(productID))>1
为您提供所有使用产品 P1 和 P2 但不是 P3 下订单的客户
DECLARE @Customer TABLE ( ID int, Name nvarchar(20) )
DECLARE @Order TABLE ( CustomerID int, Product nvarchar(2) )
INSERT INTO @Customer VALUES ( 1, 'Dave' )
INSERT INTO @Customer VALUES ( 2, 'Another Dave' )
INSERT INTO @Order VALUES ( 1, 'P1' )
INSERT INTO @Order VALUES ( 1, 'P2' )
INSERT INTO @Order VALUES ( 2, 'P1' )
INSERT INTO @Order VALUES ( 2, 'P2' )
INSERT INTO @Order VALUES ( 2, 'P3' )
SELECT a.Name
FROM @Customer a
INNER JOIN @Order b ON ( b.CustomerID = a.ID AND b.Product = 'P1' )
INNER JOIN @Order c ON ( c.CustomerID = a.ID AND c.Product = 'P2' )
LEFT OUTER JOIN @Order d ON ( d.CustomerID = a.ID AND d.Product = 'P3' )
WHERE d.CustomerID IS NULL
GROUP BY a.Name
select CustomerId
from
(
select o.*,
(case when productid = <product1> then 1 else 0 end) as has_p1,
(case when productid = <product2> then 1 else 0 end) as has_p2,
(case when productid = <product3> then 1 else 0 end) as has_p3
from Orders o
) o
group by CustomerId
having max(has_p1) = 1
and max(has_p2) = 1
and max(has_p3) = 0
select CustomerId
from
(
select o.*,
(case when productid = <product1> then 1 else 0 end) as has_p1,
(case when productid = <product2> then 1 else 0 end) as has_p2,
(case when productid = <product3> then 1 else 0 end) as has_p3
from Orders o
) o
group by CustomerId
having max(has_p1) = 1