``Pour chaque article, trouvez le ou les vendeurs ayant le plus haut prix.''
En ANSI SQL, je l'aurais fait de cette fa¸on avec une sous-requête :
SELECT article, dealer, price FROM shop s1 WHERE price=(SELECT MAX(s2.price) FROM shop s2 WHERE s1.article = s2.article);
En MySQL il vaut mieux le faire en plusieurs étapes :
Récupérer la liste de couples article et plus grand prix.
Pour chaque article, récupérer la ligne qui a le plus grand prix stocké.
Cela se fait facilement avec une table temporaire :
CREATE TEMPORARY TABLE tmp ( article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL, price DOUBLE(16,2) DEFAULT '0.00' NOT NULL); LOCK TABLES shop read; INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article; SELECT shop.article, dealer, shop.price FROM shop, tmp WHERE shop.article=tmp.article AND shop.price=tmp.price; UNLOCK TABLES; DROP TABLE tmp;
Si vous n'utilisez pas une table TEMPORARY
,
vous devez aussi verrouiller celle-ci.
``Peut-on le faire avec une seule requête ?''
Oui, mais en utilisant une astuce inefficace que j'appelle
``astuce du MAX-CONCAT
'' :
SELECT article, SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer, 0.00+LEFT( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price FROM shop GROUP BY article; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0001 | B | 3.99 | | 0002 | A | 10.99 | | 0003 | C | 1.69 | | 0004 | D | 19.95 | +---------+--------+-------+
Le dernier exemple peut, bien sûr, être amélioré en découpant les colonnes concaténées dans le client.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.