2010-11-03 3 views
2

je la requête suivante:Cette requête doit-elle être imbriquée?

select group_concat(customer_name) customer_names, 
     count(customer_name) number_of_customers, 
     line_1, 
     line_2, 
     city, 
     state_name, 
     zip 
    from (select c.name customer_name, 
       ad.*, 
       s.name state_name 
      from address ad 
      join account_address aa on aa.address_id = ad.id 
      join account a on aa.account_id = a.id 
      join customer c on a.customer_id = c.id 
      join state s on ad.state_id = s.id 
group by c.name) a 
group by state_name, city, line_1, line_2 
order by state_name, city, line_1, line_2 

Est-ce que je dois imbriquer la façon dont je l'ai fait pour obtenir les deux couches de regroupement? Je préférerais ne pas avoir de sous-requêtes si je n'ai pas à le faire.

Edit: c'est la requête que je fini par utiliser:

select group_concat(distinct c.name) customer_names, 
     count(distinct c.name) number_of_customers, 
     line_1, 
     line_2, 
     city, 
     s.name, 
     zip 
    from address ad 
    join account_address aa on aa.address_id = ad.id 
    join account a on aa.account_id = a.id 
    join customer c on a.customer_id = c.id 
    join state s on ad.state_id = s.id 
group by s.name, city, zip, line_1, line_2 
order by s.name, city, zip, line_1, line_2 
+0

Ouais, MySQL. Je dois ajouter plus de caractères à ce commentaire pour qu'il soit "valide" parce que Stack Overflow est stupide. J'espère que vous êtes heureux, Stack Overflow. –

+0

Y a-t-il une raison pour laquelle vous êtes anti-sous-requête? – JNK

+0

@JNK: ils sont quelque peu inefficaces dans MySQL (ils sont tamponnés avant d'être traités). Il y a une raison de les éviter. Et ce ne sont pas les sous-requêtes, ce sont des vues en ligne. – Quassnoi

Répondre

1

La requête la plus interne sélectionne une adresse (aléatoire) de tous ceux qui sont définis pour clients avec les mêmes noms. (Le state, en passant, n'a même pas à appartenir à l'adresse)

La requête semble compter les clients par l'état, la ville et l'adresse. Que faire si le client a plus d'une adresse? Devraient-ils être comptés une ou deux fois (et si une fois, à quelle adresse)?

En d'autres termes, ce qui devrait le retour de requête pour des adresses comme ceci:

Customer1 NY NYC Broadway 
Customer1 CA LA Sunset Boulevard 
Customer2 CA LA Sunset Boulevard 

Avez-vous trois ou deux clients au total? Si deux, vivent-ils tous les deux dans LA?

Mise à jour:

Si vous voulez des doublons sur chaque adresse, vous n'avez pas besoin du GROUP BY plus à l'intérieur du tout:

SELECT GROUP_CONCAT (DISTINCT customer_name) customer_names, 
     COUNT(DISTINCT customer_name) number_of_customers, 
     line_1, 
     line_2, 
     city, 
     state_name, 
     zip 
FROM address ad 
JOIN state s 
ON  s.id = ad.state_id 
JOIN account_address aa 
ON  aa.address_id = ad.id 
JOIN account a 
ON  a.id = aa.account_id 
JOIN customer c 
ON  c.id = a.customer_id 
GROUP BY 
     ad.state_id, ad.city, ad.line_1, ad.line_2 

Créer un index sur address (state_id, city, line_1, line_2) pour que cela fonctionne plus rapidement.

Notez que s'il est possible d'avoir différents codes postaux pour les mêmes adresses, il n'est pas défini lequel d'entre eux sera retourné.

+0

Mon objectif final est de montrer des groupes de clients qui partagent des adresses. –

+0

Le résultat que je voudrais ici est une ligne montrant ({Customer1, Customer2}, Sunset Boulevard) et une autre ligne montrant ({Customer1}, Broadway). –

+0

@Jason: alors vous n'avez pas besoin du "GROUP BY" le plus profond du tout. – Quassnoi

1

Compte tenu de vos deux autres colonnes utilisent des fonctions d'agrégation, je ne pense pas que vous avez besoin de la requête imbriquée. Mais sans le tester contre vos données, il est difficile d'être sûr.

Essayez et voir

select group_concat(customer_name) customer_names, 
     count(customer_name) number_of_customers, 
     line_1, 
     line_2, 
     city, 
     state_name, 
     zip 
      from address ad 
      join account_address aa on aa.address_id = ad.id 
      join account a on aa.account_id = a.id 
      join customer c on a.customer_id = c.id 
      join state s on ad.state_id = s.id 
group by state_name, city, zip, line_1, line_2 
order by state_name, city, zip, line_1, line_2 

Vous devez préfixer vraiment vos colonnes avec des tables dans ces types de requêtes, à savoir c.customer_name

+0

Votre requête a fonctionné (après que j'ai changé de nom d'état à s.name, etc.) mais il a donné un nombre légèrement différent de résultats (7746 contre mon 7667). Je ne sais pas quel résultat est le bon (probablement le vôtre). –

+0

@Jason, intéressant. Difficile à dire sans voir les données. Mais basé strictement sur votre structure de table, je dirai humblement que ce qui précède est probablement la meilleure question. –

+0

Vous avez raison - la vôtre était la bonne. –

Questions connexes