No existe un equivalente exacto para convertir una consulta de Postgresql que utilice SELECT DISTINCT ON en MySQL.
Postgresql SELECCIONE DISTINTO EN
En Postgresql, la siguiente consulta eliminará todas las filas donde las expresiones (col1, col2, col3)
coincidencia, y solo mantendrá la "primera fila col4, col5" para cada conjunto de filas coincidentes:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
Así que si tu mesa es así:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
nuestra consulta mantendrá solo una fila para (1,2,3) y una fila para (3,3,3). Las filas resultantes serán entonces:
col4 | col5
-----------
777 | 888
555 | 555
tenga en cuenta que la "primera fila" de cada conjunto es impredecible, nuestra primera fila también podría ser (888, 999) a menos que especifiquemos un ORDEN POR:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(las expresiones DISTINCT on deben coincidir con las expresiones ORDER BY que se encuentran más a la izquierda, pero ORDER BY puede contener expresiones adicionales).
Extensión MySQL para GROUP BY
MySQL amplía el uso de GROUP BY para que podamos seleccionar columnas no agregadas no nombradas en la cláusula GROUP BY. Siempre que seleccionamos columnas no agregadas, el servidor es libre de elegir cualquier valor de cada grupo de esa columna, por lo que los valores resultantes serán indeterminados.
Así que esta consulta de Postgresql:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
puede considerarse equivalente a esta consulta de MySQL:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
tanto Postgresql como MySQL devolverán la "Primera fila" para cada uno (col1, col2, col3), y en ambos casos la fila devuelta es impredecible porque no especificamos ni ordenamos por cláusula.
Mucha gente estaría muy tentada a convertir esta consulta de Postgresql con ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
con este:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
la idea aquí es aplicar ORDER BY a una subconsulta para que cuando MySQL agrupe por col1, col2, col3, mantenga el primer valor encontrado para col4 y col5. La idea es buena, ¡pero está mal! MySQL es libre de elegir cualquier valor para col4 y col5, y no sabemos cuáles son los primeros valores encontrados, depende del optimizador. Así que lo corregiría a esto:
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
pero esto empieza a complicarse.
Conclusión
Como regla general, no hay una forma exacta de convertir una consulta de Postgresql en una consulta de MySQL, pero hay muchas soluciones alternativas, la consulta resultante puede ser tan simple como la original o puede volverse muy complicada, pero depende de la consulta en sí.