J'ai deux tables que j'essaye de rejoindre. On contient une liste de clients, l'autre est une liste des commandes. J'essaie de formuler une requête qui me permettra de sélectionner tous les clients répertoriés dans la table les clients em> qui ont au moins une commande dans la table commandes em>. Cependant, je ne veux pas avoir des doublons pour ces clients qui ont plusieurs commandes. Toute suggestion comment je peux accomplir cela? P>
Je sais que c'est probablement un problème courant, mais je n'ai aucune idée de ce que ce type de requête serait appelé afin que je puisse rechercher une réponse. Toutes les suggestions seraient grandement appréciées. Merci. P>
4 Réponses :
C'est beaucoup plus simple que vous ne le pensez: P>
Edit: Si vous voulez réellement avoir la pleine information sur le client, P>
Sélectionnez Distinct (Customer_id) à partir de commandes; Code> p>
Sélectionnez * des clients où Customer_id In (Sélectionnez Distinct (Customer_id) à partir de commandes); Code> P>
Merci, cela ressemble à cela donnera la meilleure chance de succès. Au fur et à mesure que les tables du client et de commande sont si importantes (180 enregistrements de 180 millions de clients, 70 millions de commandes) en utilisant des clients distincts, en particulier sur les clients, est problématique.
Je ne pense pas que le distinct est nécessaire dans la sous-requête - Vérifiez le plan d'explication avec et sans cela pour voir s'il y a une différence.
select customers.id, customers.name, count(orders.id) from customers inner join orders on orders.customer_id = customers.Id group by customers.id, customers.name having count(orders.id) > 0
Si tout ce que vous retournez est Customer_ID et le nombre de commandes, il n'est pas nécessaire de faire une jointure. Sélectionnez Customer_id, Count (*) du groupe Commandes par Customer_ID CODE> fera le tour.
Ma règle générale est si la table ne figure pas dans le jeu de résultats, je ne le rejoints pas, je n'ai pas à construire groupe par / etc pour filtrer les doublons.
@OMG: HMMM, règle intéressante. Logique.
SELECT
c.id,
c.name
FROM
customer c
INNER JOIN order o ON o.customer_id = c.id
GROUP BY
c.id,
c.name
HAVING
COUNT(o.id) >= 1
Can't remember if HAVING or GROUP BY comes first.
Utilisation:
SELECT c.*
FROM CUSTOMERS c
WHERE EXISTS (SELECT NULL
FROM ORDERS o
WHERE o.custeromid = c.id)
Effectuera-t-il non seulement (beaucoup) mieux s'il y a un index sur o.customéride code>?
@Klaus Byskov Hoffmann: Vous devrez tester et voir, mais que vous sortez sur le premier match, cela me semble mieux que de comparer à tous. Le type de données pourrait jouer un rôle dans cela aussi.
Oui, je suis d'accord que la sortie du premier match est probablement presque toujours meilleure. Je pensais juste au pire des cas et je ne posais que de demander un intérêt théorique :-)
Merci d'avoir souligné que cela existe mieux fonctionne pour la duplication! Très utile
Mais il ne retournera que les archives de clients seulement, que si je veux récupérer des enregistrements de table de commande en soi
Avez-vous essayé avec distinct b>?