MySQL Query查找订购了两种特定产品的客户

时间:2009-11-04 21:46:13

标签: sql mysql

我无法提出查询,找到所有已购买PROD1和PROD2的客户。

这是一个伪查询,看起来像我想要做的事情:(显然这不起作用)

SELECT COUNT(DISTINCT userid) 
  FROM TRANSACTIONS 
 WHERE product_id = 'prod1' 
   AND product_id = 'prod2'

所以基本上我正在尝试计算product_id“transactions”和“prod1prod2表中有交易的不同用户ID的数量。每个事务都存储在transactions表中的一行中。

6 个答案:

答案 0 :(得分:5)

SELECT userid
  FROM TRANSACTIONS
 WHERE product_id in ('prod1', 'prod2')
GROUP BY userid
HAVING COUNT(DISTINCT product_id) = 2

答案 1 :(得分:5)

我通过以下方式进行此类查询:

SELECT COUNT(DISTINCT t1.userid) AS user_count
  FROM TRANSACTIONS t1
  JOIN TRANSACTIONS t2 USING (userid)
 WHERE t1.product_id = 'prod1' 
   AND t2.product_id = 'prod2';

@najmeddine的GROUP BY解决方案shown也会产生你想要的答案,但它在MySQL上表现不佳。 MySQL很难优化GROUP BY个查询。

您应该尝试两个查询,使用EXPLAIN分析优化,并运行一些测试并根据数据库中的数据量计算结果。

答案 2 :(得分:2)

(使用用户提供的附加信息在下面添加了新选项)

尝试

SELECT * FROM Customers WHERE 
 EXISTS (SELECT * FROM Purchases WHERE ProductID = 'PROD1' AND CustID = Customers.CustID)
 AND
 EXISTS (SELECT * FROM Purchases WHERE ProductID = 'PROD2' AND CustID = Customers.CustID)

或者

SELECT * FROM Customers WHERE 
 CustID IN (SELECT CustID FROM Purchases WHERE ProductID = 'PROD1')
 AND
 CustID IN (SELECT CustID FROM Purchases WHERE ProductID = 'PROD2')

或者

SELECT UserID FROM Transactions WHERE ProductID = 'PROD1'
 AND EXISTS (SELECT * FROM Transactions WHERE UserID = T1.UserID 
  AND ProductID = 'PROD2')

或者

SELECT UserID FROM Transactions WHERE ProductID = 'PROD1'
 AND UserID IN (SELECT UserID FROM Transactions WHERE ProductID = 'PROD2')

答案 3 :(得分:0)

这是一个基于臭名昭着的Northwind示例数据库的Access答案。你应该很容易在mySql中翻译它。

SELECT o.CustomerID, Sum([ProductID]='Prod1') AS Expr1, Sum([productid]='Prod1') AS Expr2
FROM Orders AS o INNER JOIN [Order Details] AS d ON o.OrderID = d.OrderID
GROUP BY o.CustomerID
HAVING (((Sum([ProductID]='Prod1'))<>0) AND ((Sum([productid]='Prod1'))<>0));

答案 4 :(得分:0)

SELECT COUNT(DISTINCT userId)
FROM(
  SELECT userId
  FROM transactions
  WHERE product = 'PROD1'
  INTERSECT
  SELECT userId
  FROM transactions
  WHERE product = 'PROD2');

查询创建两个中间表,一个包含购买PROD1的客户的userId,另一个包含购买PROD2的用户的相同表。 交集运算符返回一个表,该表仅包含在前两个表中找到的行,即那些购买两个产品的行。

答案 5 :(得分:0)

sakila db的例子:

SELECT R.customer_id, GROUP_CONCAT(I.film_id) 
FROM sakila.rental R 
RIGHT OUTER JOIN sakila.inventory I ON R.inventory_id = I.inventory_id 
WHERE I.film_id IN (22,44) GROUP BY R.customer_id HAVING COUNT(*) = 2