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
またはのいずれかを含む 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')
)
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
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 を注文しなかったすべての顧客を示します。