1

它位于 SQL Server 2008 R2 中。

我们有 3 种产品,订单和客户:P1 P2 P3

我们想知道订购 P1 和 P2 但不订购 P3 的客户。我们不希望得到订购所有 3 种产品的客户。我不知道如何编写该查询。你能告诉我吗?谢谢。

我们只有 2 张桌子。订单和客户。产品名称是固定的。

4

5 回答 5

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的订单。P2P3

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')
                 )
于 2012-04-13T15:43:40.530 回答
0

假设 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 下订单的客户

于 2012-04-13T15:18:04.193 回答
0
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
于 2012-04-13T16:16:45.223 回答
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 
  and max(has_p2) = 1 
  and max(has_p3) = 0
于 2012-04-13T18:06:26.010 回答
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 
于 2013-08-19T18:53:13.057 回答