Question

Considérez ce tableau (de http://www.tizag.com/mysqlTutorial/mysqlmax. php ):

Id     name               type     price 
123451 Park's Great Hits  Music    19.99 
123452 Silly Puddy        Toy      3.99 
123453 Playstation        Toy      89.95 
123454 Men's T-Shirt      Clothing 32.50 
123455 Blouse             Clothing 34.97 
123456 Electronica 2002   Music    3.99 
123457 Country Tunes      Music    21.55 
123458 Watermelon         Food     8.73

Cette requête SQL retourne le plus cher de l'article chaque type: le type SELECT, MAX (prix) des produits GROUP BY de type

Clothing $34.97
Food     $8.73
Music    $21.55
Toy      $89.95

Je veux aussi les champs id et nom qui appartiennent au-dessus du prix maximum, pour chaque ligne. Qu'est-ce que la requête SQL retourne une table comme ça?

Id     name            type      price
123455 Blouse          Clothing  34.97
123458 Watermelon      Food      8.73
123457 Country Tunes   Music     21.55
123453 Playstation     Toy       89.95
Était-ce utile?

La solution

Ceci est le problème de greatest-n-per-group qui revient souvent. Ma façon habituelle de résoudre est logiquement équivalente à la réponse donnée par Smith @ Martin, mais ne pas utiliser une sous-requête:

SELECT T1.Id, T1.name, T1.type, T1.price 
FROM Table T1
LEFT OUTER JOIN Table T2
  ON (T1.type = T2.type AND T1.price < T2.price)
WHERE T2.price IS NULL;

Ma solution et tous les autres données sur ce fil jusqu'à présent une chance de produire de multiples lignes par valeur de type, si plus d'une part de ce produit le même type et ont tous deux un prix égal qui est au maximum. Il existe des moyens de résoudre ce problème et briser le lien, mais vous devez nous dire quel produit « gagne » en cas comme ça.

Vous avez besoin d'un autre attribut qui est garanti d'être unique sur toutes les lignes, au moins pour les lignes avec le même type. Par exemple, si le produit avec la plus grande valeur Id devrait gagner, vous pouvez résoudre le lien de cette façon:

SELECT T1.Id, T1.name, T1.type, T1.price 
FROM Table T1
LEFT OUTER JOIN Table T2
  ON (T1.type = T2.type AND (T1.price < T2.price
       OR T1.price = T2.price AND T1.Id < T2.Id))
WHERE T2.price IS NULL;

Autres conseils

Modifier mise à jour de la mine Juste pour répondre à l'exigence de clarifier

SELECT Id, name, type,price 
FROM Table T1
WHERE NOT EXISTS(
          SELECT * FROM TABLE T2 
          WHERE T1.type=t2.type 
          AND T2.Price >= T1.Price 
          AND T2.Id > T1.Id
          )

Vous pouvez le faire avec un sous-sélection

SELECT id, name, type, price FROM products p1
WHERE EXISTS (Select type, max(price) FROM Products p2 
              GROUP BY type
              WHERE p1.type=p2.type AND p1.price=p2.MAX(price))

ou une jointure interne

SELECT id, name, type, price FROM products p1
INNER JOIN (Select type, max(price) FROM Products p2 GROUP BY type) maxPrice
         ON maxPrice=price=p1.price AND maxPrice.type=p1.price
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top