[英]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.