2013-02-28 5 views
0

J'apprends manuel mysql: http://dev.mysql.com/doc/refman/5.6/en/example-maximum-column-group-row.html et je suis confondu avec le « where.s1.article = s2.article » une partie, ce qui est ce que cela signifiesous-requête mysql où et par groupe

Task: For each article, find the dealer or dealers with the most expensive price. 

+---------+--------+-------+ 
| article | dealer | price | 
+---------+--------+-------+ 
| 0001 | A  | 3.45 | 
| 0001 | B  | 3.99 | 
| 0002 | A  | 10.99 | 
| 0003 | B  | 1.45 | 
| 0003 | C  | 1.69 | 
| 0003 | D  | 1.25 | 
| 0004 | D  | 19.95 | 
+---------+--------+-------+ 


SELECT article, dealer, price 
FROM shop s1 
WHERE price=(SELECT MAX(s2.price) 
       FROM shop s2 
       WHERE s1.article = s2.article); 

+---------+--------+-------+ 
| article | dealer | price | 
+---------+--------+-------+ 
| 0001 | B  | 3.99 | 
| 0002 | A  | 10.99 | 
| 0003 | C  | 1.69 | 
| 0004 | D  | 19.95 | 
+---------+--------+-------+ 
?

Je suis en train d'écrire le code similaire:

SELECT sex, name, birthday 
From user 
Where birthday=(SELECT MAX(birthday) 
       FROM user 
       group by sex); 

Mais mes sorties l'erreur: retour de sous-requête plus de 1 ligne, pourquoi

+1

Je ne suis pas sûr, je peux me tromper, mais je pense que c'est parce que 'la sous-requête renvoie plus de 1 rangée'. – Sebas

Répondre

5

la requête originale? est appelé une sous-requête corrélée. La clause WHERE dans la sous-requête restreint le maximum trouvé à juste l'article qui correspond à la ligne en cours de traitement par la requête externe.

Dans votre requête, vous n'avez pas de clause WHERE, donc tout est traité dans la table. Il renvoie ensuite les résultats regroupés par sexe. Je suppose qu'il y a deux sexes dans votre tableau, donc il retourne une rangée avec le maximum pour les hommes, et une autre rangée contenant le maximum pour les femmes. Mais WHERE price = (<subquery>) nécessite que la sous-requête retourne un seul résultat, car = ne peut être utilisé qu'avec des valeurs uniques.

Vous pouvez utiliser IN au lieu de = pour faire correspondre à plusieurs valeurs renvoyées. Ce n'est probablement pas ce que vous voulez, mais vous n'avez pas décrit ce que vous voulez que votre requête fasse, c'est difficile à dire.

Pour obtenir la plus jeune personne de chaque sexe, vous pouvez écrire une sous-requête corrélée, comme celui dans le manuel:

select sex, name, birthday 
from user u1 
where birthday = (select max(birthday) 
        from user u2 
        where u1.sex = u2.sex) 

ou vous pouvez utiliser une jointure avec une sous-requête groupée:

select u1.sex, name, u1.birthday 
from user u1 
join (select sex, max(birthday) maxbirthday 
     from user 
     group by sex) u2 
on u1.sex = u2.sex and birthday = maxbirthday 
+0

Je vois, merci! – nut

+0

J'ai mis à jour mon code, je viens de coller le mauvais, c'est peut-être clair pour tous ceux qui voient ce post. – nut

+0

C'est toujours le même problème. La sous-requête renvoie deux anniversaires, un pour les hommes, un autre pour les femmes. Mais '=' ne nécessite qu'une seule chose à comparer. Si vous voulez corréler, vous devez utiliser une clause 'WHERE'. – Barmar