Non esiste un equivalente esatto per convertire una query Postgresql che utilizza SELECT DISTINCT ON in MySQL.
Postgresql SELEZIONA DISTINTO ATTIVO
In Postgresql, la query seguente eliminerà tutte le righe in cui le espressioni (col1, col2, col3)
corrispondenza e manterrà solo la "prima riga col4, col5" per ogni set di righe abbinate:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
Quindi se la tua tabella è così:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
la nostra query manterrà solo una riga per (1,2,3) e una riga per (3,3,3). Le righe risultanti saranno quindi:
col4 | col5
-----------
777 | 888
555 | 555
si prega di notare che la "prima riga" di ogni set è imprevedibile, anche la nostra prima riga potrebbe essere (888, 999) a meno che non specifichiamo un ORDINE PER:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(il DISTINCT sulle espressioni deve corrispondere alle espressioni ORDER BY più a sinistra, ma ORDER BY può contenere espressioni aggiuntive).
Estensione MySQL per GROUP BY
MySQL estende l'uso di GROUP BY in modo da poter selezionare colonne non aggregate non nominate nella clausola GROUP BY. Ogni volta che selezioniamo colonne non aggregate, il server è libero di scegliere qualsiasi valore da ciascun gruppo di quella colonna, quindi i valori risultanti saranno indeterminati.
Quindi questa query Postgresql:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
può essere considerato equivalente a questa query MySQL:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
sia Postgresql che MySQL restituiranno la "Prima riga" per ciascuno (col1, col2, col3) e in entrambi i casi la riga restituita è imprevedibile perché non abbiamo specificato e ordinato per clausola.
Molte persone sarebbero molto tentate di convertire questa query Postgresql con un ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
con questo:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
l'idea qui è di applicare un ORDER BY a una sottoquery in modo che quando MySQL raggruppa per col1, col2, col3 manterrà il primo valore incontrato per col4 e col5. L'idea è buona, ma è sbagliata! MySQL è libero di scegliere qualsiasi valore per col4 e col5 e non sappiamo quali siano i primi valori incontrati, dipende dall'ottimizzatore. Quindi lo correggerei in questo modo:
SELECT t1.col4, t1.col5
FROM tablename t1 INNER JOIN (SELECT col1, col2, col3, MIN(col4) as m_col4
FROM tablename
GROUP BY col1, col2, col3) s
ON t1.col1=s.col1
AND t1.col2=s.col2
AND t1.col3=s.col3
AND t1.col4=s.m_col4
GROUP BY
t1.col1, t1.col2, t1.col3, t1.col4
ma questo inizia a diventare più complicato.
Conclusione
Come regola generale, non esiste un modo esatto per convertire una query Postgresql in una query MySQL, ma ci sono molte soluzioni alternative, la query risultante potrebbe essere semplice come quella originale o potrebbe diventare molto complicata, ma dipende da la query stessa.