看到的,觉得很有用记录下来
问题描述很简单,就是查询购买了产品A和B但是没有购买产品C的顾客
测试数据
--===== Conditionally drop the test table to make -- reruns in SSMS easier. IF OBJECT_ID('tempdb..#Purchase','U') IS NOT NULL DROP TABLE #Purchase ; --===== Create the test table CREATE TABLE #Purchase ( PurchaseID INT IDENTITY(1,1), CustomerID INT, ProductCode CHAR(1) PRIMARY KEY CLUSTERED (PurchaseID) ) ; --===== Populate the test table with known data. INSERT INTO #Purchase (CustomerID, ProductCode) ------- Customer #1 precisely meets the criteria. -- Bought 'A' and 'B' but not 'C'. SELECT 1, 'A' UNION ALL SELECT 1, 'B' UNION ALL ------- Customer #2 also meets the criteria. -- Bought 'A' and 'B' and somthing else, -- but not 'C'. SELECT 2, 'A' UNION ALL SELECT 2, 'B' UNION ALL SELECT 2, 'D' UNION ALL ------- Customer #3 also meets the criteria. -- Bought 'A' and 'B' and something else, -- but not 'C'. SELECT 3, 'A' UNION ALL SELECT 3, 'B' UNION ALL SELECT 3, 'D' UNION ALL SELECT 3, 'A' UNION ALL SELECT 3, 'D' UNION ALL ------- Customer #4 doesn't meet the criteria. -- Bought 'A' and 'B' but also bought 'C'. SELECT 4, 'A' UNION ALL SELECT 4, 'B' UNION ALL SELECT 4, 'C' UNION ALL ------- Customer #5 doesn't meet the criteria. -- Bought 'A' and 'B' and something else, -- but also bought 'C'. SELECT 5, 'A' UNION ALL SELECT 5, 'B' UNION ALL SELECT 5, 'A' UNION ALL SELECT 5, 'B' UNION ALL SELECT 5, 'C' UNION ALL SELECT 5, 'D' UNION ALL ------- Customer #6 doesn't meet the criteria. -- Bought more than 1 of 'A' and something else -- but not 'B'. SELECT 6, 'A' UNION ALL SELECT 6, 'A' UNION ALL SELECT 6, 'D' UNION ALL SELECT 6, 'E' UNION ALL ------- Customer #7 doesn't meet the criteria. -- Bought more than 1 of 'B' and something else -- but not 'A'. SELECT 7, 'B' UNION ALL SELECT 7, 'B' UNION ALL SELECT 7, 'D' UNION ALL SELECT 7, 'E' ;
中间跳过一些简单过程。测试数据中顾客6买了两个A但没有买B, 顾客7买了两个B但是没有买A。他们不应该出现在同时购买A和B的顾客集中
查询语句
--===== Find Customers that bought "A" AND "B" -- HAVING is like a WHERE for GROUP BYs. SELECT CustomerID FROM #Purchase WHERE ProductCode IN ('A','B') GROUP BY CustomerID HAVING COUNT(DISTINCT ProductCode) = 2 ;
查询结果
CustomerID ----------- 1 2 3 4 5
现在从上面的结果中剔除买了C的顾客
FROM #Purchase WHERE ProductCode IN ('A','B') GROUP BY CustomerID HAVING COUNT(DISTINCT ProductCode) = 2 EXCEPT --===== Find Customers that bought "C". SELECT CustomerID FROM #Purchase WHERE ProductCode IN ('C') ;
查询结果
CustomerID ----------- 1 2 3
搞定