获取尚未订购特定产品的客户列表

时间:2012-04-13 14:51:09

标签: sql sql-server sql-server-2008 tsql exists

它位于SQL Server 2008 R2中。

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

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

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

5 个答案:

答案 0 :(得分: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

首先,联接会过滤所有包含订单的内容,包括P1P2P3的任意内容。

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')
                 )

答案 1 :(得分:0)

假设订单包含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

的客户

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分: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