Pregunta

Considere esta tabla (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

Esta consulta SQL devuelve el elemento más caro de cada tipo: tipo SELECT, MAX (precio) de los productos de GRUPO POR escriba

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

También quieren obtener los campos id y nombre que pertenecen al precio máximo superior, para cada fila. ¿Qué consulta SQL devolverá una tabla como ésta?

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
¿Fue útil?

Solución

Este es el problema greatest-n-per-group que aparece con frecuencia. Mi forma habitual de resolver es lógicamente equivalente a la respuesta dada por @ Martin Smith, pero no utiliza una subconsulta:

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;

Mi solución y todos los demás dados en este hilo hasta ahora tienen la oportunidad de producir múltiples filas por valor de type, si hay más de uno comparte de productos del mismo tipo y ambos tienen un precio igual que es el máximo. Hay maneras de resolver esto y romper el empate, pero es necesario que nos diga qué producto "gana" en el caso de esa manera.

Se necesita algún otro atributo que se garantiza que sea único sobre todas las filas, al menos para las filas con el mismo type. Por ejemplo, si el producto con el valor Id mayor debe ganar, puede resolver el empate de esta manera:

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;

Otros consejos

Editar Sólo la actualización mina para cumplir con el requisito aclarado

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
          )

Puede hacerlo con una subselección

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

o un combinación interna

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top