Der er ikke en nøjagtig ækvivalent til at konvertere en Postgresql-forespørgsel, der gør brug af SELECT DISTINCT ON til MySQL.
Postgresql VÆLG DISTINCT ON
I Postgresql vil følgende forespørgsel eliminere alle rækker, hvor udtrykkene (col1, col2, col3)
match, og det vil kun beholde den "første col4, col5 row" for hvert sæt matchede rækker:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
Så hvis dit bord er sådan her:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
vores forespørgsel vil kun beholde en række for (1,2,3) og en række for (3,3,3). De resulterende rækker vil derefter være:
col4 | col5
-----------
777 | 888
555 | 555
Bemærk venligst, at den "første række" i hvert sæt er uforudsigelig, vores første række kan også være (888, 999), medmindre vi angiver en BESTILLING AF:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(DISTINCT på udtryk skal matche ORDER BY-udtrykkene længst til venstre, men ORDER BY kan indeholde yderligere udtryk).
MySQL-udvidelse til GROUP BY
MySQL udvider brugen af GROUP BY, så vi kan vælge ikke-aggregerede kolonner, der ikke er navngivet i GROUP BY-sætningen. Når vi vælger ikke-aggregerede kolonner, kan serveren frit vælge en hvilken som helst værdi fra hver gruppe fra den kolonne, så de resulterende værdier vil være ubestemte.
Så denne Postgresql-forespørgsel:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
kan betragtes som svarende til denne MySQL-forespørgsel:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
både Postgresql og MySQL vil returnere "Første række" for hver (col1, col2, col3), og i begge tilfælde er den returnerede række uforudsigelig, fordi vi ikke specificerede og sorterede efter klausul.
Mange mennesker ville være meget fristet til at konvertere denne Postgresql-forespørgsel med en ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
med denne:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
Ideen her er at anvende en ORDER BY til en underforespørgsel, så når MySQL grupperer efter col1, col2, col3, vil den beholde den først stødte værdi for col4 og col5. Ideen er god, men den er forkert! MySQL kan frit vælge en hvilken som helst værdi for col4 og col5, og vi ved ikke, hvilke værdier der først støder på, det afhænger af optimizeren. Så jeg ville rette det til dette:
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 dette begynder at blive mere kompliceret.
Konklusion
Som en generel regel er der ikke en nøjagtig måde at konvertere en Postgresql-forespørgsel til en MySQL-forespørgsel, men der er mange løsninger, den resulterende forespørgsel kan være lige så enkel som den originale, eller den kan blive meget kompliceret, men det afhænger af selve forespørgslen.