Det finns ingen exakt motsvarighet till att konvertera en Postgresql-fråga som använder SELECT DISTINCT ON till MySQL.
Postgresql VÄLJ DISTINCT PÅ
I Postgresql kommer följande fråga att eliminera alla rader där uttrycken (col1, col2, col3)
matcha, och det kommer bara att behålla den "första kol4, kol5 raden" för varje uppsättning matchade rader:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
Så om ditt bord är så här:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
vår fråga kommer bara att behålla en rad för (1,2,3) och en rad för (3,3,3). De resulterande raderna blir då:
col4 | col5
-----------
777 | 888
555 | 555
Observera att den "första raden" i varje uppsättning är oförutsägbar, vår första rad kan också vara (888, 999) om vi inte anger en BESTÄLLNING AV:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(DISTINCT på uttryck måste matcha ORDER BY-uttrycken längst till vänster, men ORDER BY kan innehålla ytterligare uttryck).
MySQL-tillägg till GROUP BY
MySQL utökar användningen av GROUP BY så att vi kan välja icke aggregerade kolumner som inte är namngivna i GROUP BY-satsen. Närhelst vi väljer icke aggregerade kolumner är servern fri att välja valfritt värde från varje grupp från den kolumnen, så de resulterande värdena kommer att vara obestämda.
Så denna Postgresql-fråga:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
kan betraktas som likvärdig med denna MySQL-fråga:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
både Postgresql och MySQL kommer att returnera "Första raden" för varje (col1, col2, col3), och i båda fallen är den returnerade raden oförutsägbar eftersom vi inte specificerade och sorterade efter klausul.
Många människor skulle vara mycket frestade att konvertera denna Postgresql-fråga med en BESTÄLLNING AV:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
med den här:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
Tanken här är att tillämpa en ORDER BY på en underfråga så att när MySQL grupperar efter col1, col2, col3 kommer det att behålla det första påträffade värdet för col4 och col5. Tanken är bra, men den är fel! MySQL är fri att välja vilket värde som helst för col4 och col5, och vi vet inte vilka som är de första värdena som påträffas, det beror på optimeraren. Så jag skulle rätta till det här:
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
men det här börjar bli mer komplicerat.
Slutsats
Som en allmän regel finns det inget exakt sätt att konvertera en Postgresql-fråga till en MySQL-fråga, men det finns många lösningar, den resulterande frågan kan vara lika enkel som den ursprungliga eller så kan den bli mycket komplicerad, men det beror på själva frågan.