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まず、結合は、 、P2またはのいずれかを含む Orders だけに所有するすべてをフィルター処理しますP3

GROUP BY は、これらを注文のグループにし、顧客ごとに 1 つのグループにします。

最初の HAVING 句は、そのリストにあるすべての注文を調べます。そのサブセットに含まれる異なる製品の数をカウントします。検索対象の製品リストに含まれる包括的な製品の数を確認します。この 2 つの数値は同じでなければならないと規定しています。
[この例では; 正確に 2 つの異なる製品を注文したに違いありません。]

2 番目の 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
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

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 に答える