2009-11-04 4 views
2

J'ai des difficultés à trouver une requête qui permette de trouver tous les clients qui ont acheté PROD1 et PROD2.MySQL Requête pour trouver des clients ayant commandé deux produits spécifiques

Voici une pseudo-requête qui ressemble un peu à ce que je veux faire: (évidemment, cela ne fonctionnerait pas)

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

fondamentalement, je suis en train d'obtenir un décompte du nombre de distincts les ID d'utilisateur ayant une transaction dans la table transactions pour les ID de produit 'prod1' et 'prod2'. Chaque transaction est stockée dans une rangée dans la table transactions.

Répondre

4

je fais ce type de requête de la manière suivante:

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

La solution GROUP BYshown par @najmeddine produit également la réponse que vous voulez, mais il ne fonctionne pas aussi bien sur MySQL. MySQL a du mal à optimiser les requêtes GROUP BY.

Vous devriez essayer les deux requêtes, en analysant l'optimisation avec EXPLAIN, et aussi exécuter quelques tests et chronométrer les résultats compte tenu du volume de données dans votre base de données.

+0

facture tout à fait raison – Ian

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

(Ajout de nouvelles options ci-dessous en utilisant les informations supplémentaires fournies par l'utilisateur)

Essayez

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) 

Ou

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

Ou

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

Ou

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

Ceci est une réponse d'accès à partir de l'échantillon Northwind infâme db. Vous devriez être capable de traduire ça dans mySql assez facilement.

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)); 
0
SELECT COUNT(DISTINCT userId) 
FROM(
    SELECT userId 
    FROM transactions 
    WHERE product = 'PROD1' 
    INTERSECT 
    SELECT userId 
    FROM transactions 
    WHERE product = 'PROD2'); 

La requête crée deux tables intermédiaires, celui qui contient userId de clients ayant acheté PROD1 et une autre table identique pour ceux qui ont acheté PROD2. L'opérateur d'intersection retourne une table qui contient uniquement les lignes trouvées dans les deux tables précédentes, c'est-à-dire celles qui ont acheté les deux produits.

0

Exemple 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 
Questions connexes