2012-10-02 3 views
10

Sto provando a creare una query in una tabella che contiene circa 500.000 record e circa 50 o 60 colonne. Ciò di cui ho bisogno è di raggruppare questi record in gruppi e selezionare il record massimo in ciascun gruppo.MySQL che seleziona il record massimo nel gruppo di

Per semplificare il problema che ho una tabella come segue

+----+-------------+----------+--------+ 
| id | external_id | group_id | mypath | 
+----+-------------+----------+--------+ 
| 1 |  1003 |  1 | a  | 
| 2 |  1004 |  2 | b  | 
| 3 |  1005 |  2 | c  | 
+----+-------------+----------+--------+ 

Il gruppo semplice da è la seguente

select * from temp GROUP BY group_id 

che restituisce

+----+-------------+----------+--------+ 
| id | external_id | group_id | mypath | 
+----+-------------+----------+--------+ 
| 1 |  1003 |  1 | a  | 
| 2 |  1004 |  2 | b  | 
+----+-------------+----------+--------+ 

Bello ma non quello che voglio . Quello che voglio è l'intero record per max enternal_id in ogni gruppo. In altre parole

+----+-------------+----------+--------+ 
| id | external_id | group_id | mypath | 
+----+-------------+----------+--------+ 
| 1 |  1003 |  1 | a  | 
| 3 |  1005 |  2 | c  | 
+----+-------------+----------+--------+ 

In qualche modo sto cercando di mettere un (external_id) dichiarazione max qui per filtrare ciò che è necessario ma finora tutta la mia inchiesta ha fallito. Alcune indicazioni sarebbero apprezzate. È importante che quando si restituisce il massimo (external_id) che l'intero record sia selezionato come la colonna del percorso differisce.

+0

Forse usando "select MAX (external_id) AS massimo, * dalla temperatura GROUP BY group_id" si può fare questo. – PiLHA

risposta

19

maggior parte delle informazioni in http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

Questo è sempre stato un problema fastidioso in MySQL. Ci sono stati dei modi per aggirarlo, come concatenare più campi insieme (iniziando con external_id), e quindi selezionare il MAX() di quello, e quindi spezzarlo.

Suggerisco di utilizzare una tabella derivata. La prima tabella (t1) è derivata da una semplice query in cui si identifica lo MAX(external_id), quindi ci si unisce da esso per ottenere il resto dei dati.

QUESTO E 'SOLO SE external_id è unico

SELECT 
    t1.group_id, some_table.id, some_table.mypath 
FROM 
    (
     SELECT group_id, MAX(external_id) AS external_id 
     FROM some_table 
     GROUP BY group_id 
    ) as t1 
INNER JOIN 
    sometable ON t1.external_id = sometable.external_id 
WHERE ... 
+0

Sì, hai perfettamente ragione. Cambiare il problema è il modo migliore, avrei dovuto seguire la regola "se hai un problema che non puoi risolvere, cambialo in uno che puoi". Con gli indici adatti funziona bene. – user1715656

+0

Domanda minore, ma esiste un motivo per cui hai scelto di selezionare t1.group_id anziché some_table.group_id? È più efficiente? –