2010-10-24 23 views
3

J'ai 3 tables:requête SQL pour regrouper les données de deux tables

  • utilisateurs (id, nom)
  • Commandes (id, userId)
  • Orders_Items (id, orderId, état)

au début, je voulais énumérer tous les utilisateurs avec leur nombre respectif de commandes comme ceci:

  • A, 1 pour
  • B, 5 commandes

C'est facile, je fais un "select nom, compte (id) des utilisateurs, commandes où users.id = orders.userId groupe par son nom" .

Maintenant, je voudrais filtrer davantage ces données pour montrer seulement aux utilisateurs avec des commandes qui ont des articles avec status = "non traité". Je ne suis pas sûr de savoir comment regrouper les données de deux tables. En fin de compte, je suis à la recherche pour obtenir des données comme:

  • (A non représentée, aucun ordre avec tout élément ayant le statut = non traité)
  • B, 3 commandes (2 commandes ont aucun élément avec le statut = non traité).

Merci!

+0

Avez-vous essayé quelque chose comme: SELECT nom, count (id) des utilisateurs, commandes, items_demandes WHERE users.id = orders.userId et orders.id = orders_items.orderid et order_items.status = 'non traité' GROUP BY name –

Répondre

1

Utilisation:

SELECT u.name, 
     COUNT(o.id) AS numOrders 
    FROM USERS u 
    JOIN ORDERS o ON o.userid = u.id 
    WHERE EXISTS(SELECT NULL 
        FROM ORDERS_ITEMS oi 
       WHERE oi.orderid = o.id 
        AND oi.status = 'unprocessed') 
GROUP BY u.name 

à l'aide d'un REJOIGNEZ ORDERS_ITEMS nécessiterait l'utilisation de DISTINCT dans le COUNT:

SELECT u.name, 
     COUNT(DISTINCT o.id) AS numOrders 
    FROM USERS u 
    JOIN ORDERS o ON o.userid = u.id 
    JOIN ORDERS_ITEMS oi ON oi.orderid = o.id 
         AND oi.status = 'unprocessed' 
GROUP BY u.name 

... en raison de la duplication de la ligne quand il y a plus d'un article non traité à une commande ...

+0

Merci! Ça a marché. J'ai utilisé la deuxième méthode car la première était environ 10 fois plus lente. – siger

0
select name, count(users.id) from users 
left join orders 
on users.id=orders.userId 
left join orders_items 
on orders.id=orders_items.orderId 
where orders_items.status="unprocessed" 

Je suis en train de tester cela maintenant, je ne sais pas si je l'ai bien. Modifier: semble bon.

+0

Vous ne souhaitez pas utiliser de jointure OUTER si vous souhaitez exclure des éléments du jeu de résultats. –

+0

merci pour le conseil, comme toujours :) – Orbit