Domanda

Si consideri questo tavolo (da 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

Questa query SQL restituisce l'elemento più costoso di ogni tipo: tipo SELECT, MAX (prezzo) FROM prodotti GROUP BY tipo

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

Ho anche voglia di ottenere i campi id e nome che appartengono al di sopra del prezzo massimo, per ogni riga. Quali query SQL restituirà una tabella come questa?

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
È stato utile?

Soluzione

Questo è il problema greatest-n-per-group che viene frequentemente. Il mio solito modo di risolvere è logicamente equivalente alla risposta data da @ Martin Smith, ma non usa una sottoquery:

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;

La mia soluzione e tutti gli altri dati su questa discussione fino ad ora hanno la possibilità di produrre più righe per ogni valore della type, se più di un prodotto condivide lo stesso tipo ed entrambi hanno un prezzo uguale, che è il massimo. Ci sono modi per risolvere questo e rompere il legame, ma è necessario dirci quale prodotto "vince" in caso del genere.

avete bisogno di qualche altro attributo che è garantito per essere unico su tutte le righe, almeno per le righe con lo stesso type. Ad esempio, se il prodotto con il valore maggiore Id dovrebbe vincere, è possibile risolvere il pareggio in questo modo:

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;

Altri suggerimenti

Modifica Just aggiornamento miniera per soddisfare il requisito chiarito

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
          )

Si può farlo con una selezione secondaria

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 join interno

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top