8
votes

MySQL - Entrant deux tables sans doublons?

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 qui ont au moins une commande dans la table commandes . Cependant, je ne veux pas avoir des doublons pour ces clients qui ont plusieurs commandes. Toute suggestion comment je peux accomplir cela?

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.


1 commentaires

Avez-vous essayé avec distinct ?


4 Réponses :


9
votes

C'est beaucoup plus simple que vous ne le pensez:

Sélectionnez Distinct (Customer_id) à partir de commandes;

Edit: Si vous voulez réellement avoir la pleine information sur le client,

Sélectionnez * des clients où Customer_id In (Sélectionnez Distinct (Customer_id) à partir de commandes);


2 commentaires

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.



2
votes
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

3 commentaires

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 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.



0
votes
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. 

0 commentaires

7
votes

Utilisation:

SELECT c.*
  FROM CUSTOMERS c
 WHERE EXISTS (SELECT NULL
                 FROM ORDERS o
                WHERE o.custeromid = c.id)


5 commentaires

Effectuera-t-il non seulement (beaucoup) mieux s'il y a un index sur o.customéride ?


@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