简体   繁体   English

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

[英]MySQL Query to find customers who have ordered two specific products

I'm having trouble coming up with a query that will find all customers who have purchased both PROD1 and PROD2. 我无法提出查询,找到所有购买了PROD1和PROD2的客户。

Here's a pseudo-query that kind of looks like what I want to do: (obviously this wouldn't work) 这是一个伪查询,看起来像我想做的事情:(显然这不起作用)

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

So basically I'm trying to get a count of the number of distinct userids that have a transaction in the transactions table for both product_id ' prod1 ' and ' prod2 '. 所以基本上,我试图让有在交易不同的用户ID的数量的计数transactions表都PRODUCT_ID“ prod1 ”和“ prod2 ”。 Each transaction is stored in a row in the transactions table. 每个事务都存储在transactions表中的一行中。

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

I do this type of query in the following way: 我通过以下方式执行此类查询:

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

The GROUP BY solution shown by @najmeddine also produces the answer you want, but it doesn't perform as well on MySQL. @najmeddine 显示GROUP BY解决方案也能产生你想要的答案,但它在MySQL上表现不佳。 MySQL has a hard time optimizing GROUP BY queries. MySQL很难优化GROUP BY查询。

You should try both queries, analyzing the optimization with EXPLAIN , and also run some tests and time the results given the volume of data in your database. 您应该尝试两种查询,使用EXPLAIN分析优化,并运行一些测试并根据数据库中的数据量计算结果。

(Added new options below using the additional information provided by the user) (使用用户提供的附加信息在下面添加了新选项)

Try 尝试

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)

Or 要么

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

Or 要么

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

Or 要么

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

This is an Access answer based on the infamous Northwind sample db. 这是一个基于臭名昭着的Northwind示例数据库的Access答案。 You should be abe to translate that in mySql quite easily. 你应该很容易在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));
SELECT COUNT(DISTINCT userId)
FROM(
  SELECT userId
  FROM transactions
  WHERE product = 'PROD1'
  INTERSECT
  SELECT userId
  FROM transactions
  WHERE product = 'PROD2');

The query creates two intermediate tables, one which contains userId of customer who bought PROD1 and another identical table for those who bought PROD2. 该查询创建了两个中间表,一个包含购买PROD1的客户的userId和另一个购买PROD2的相同表。 The intersection operator returns a table which contains only rows found in both previous tables, ie those who bought both products. 交集运算符返回一个表,该表仅包含在前两个表中找到的行,即那些购买两个产品的表。

Example for sakila db: 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM