Няма точен еквивалент за преобразуване на Postgresql заявка, която използва SELECT DISTINCT ON към MySQL.
Postgresql SELECT DISTINCT ON
В Postgresql следната заявка ще премахне всички редове, където изразите (col1, col2, col3)
съвпадение и ще запази само "първото col4, col5 row" за всеки набор от съвпадащи редове:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
Така че, ако вашата таблица е следната:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
нашата заявка ще запази само един ред за (1,2,3) и един ред за (3,3,3). След това получените редове ще бъдат:
col4 | col5
-----------
777 | 888
555 | 555
моля, обърнете внимание, че "първият ред" от всеки набор е непредсказуем, първият ни ред може също да бъде (888, 999), освен ако не посочим ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(DISTINCT на изразите трябва да съвпада с най-левите изрази ORDER BY, но ORDER BY може да съдържа допълнителни изрази).
Разширение на MySQL към GROUP BY
MySQL разширява използването на GROUP BY, така че да можем да избираме неагрегирани колони, които не са наименувани в клаузата GROUP BY. Всеки път, когато избираме неагрегирани колони, сървърът е свободен да избере всяка стойност от всяка група от тази колона, така че получените стойности ще бъдат неопределени.
Така че това Postgresql заявка:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
може да се счита за еквивалентна на тази MySQL заявка:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
както Postgresql, така и MySQL ще върнат „Първия ред“ за всеки (col1, col2, col3), като и в двата случая върнатият ред е непредсказуем, защото не сме посочили и подредихме по клауза.
Много хора биха били много изкушени да преобразуват тази заявка Postgresql с ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
с този:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
идеята тук е да се приложи ORDER BY към подзаявка, така че когато MySQL групира по col1, col2, col3, тя ще запази първата срещана стойност за col4 и col5. Идеята е добра, но е грешна! MySQL е свободен да избере всяка стойност за col4 и col5 и не знаем кои са първите стойности, които се срещат, зависи от оптимизатора. Така че бих го коригирал до това:
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
но това започва да става по-сложно.
Заключение
Като общо правило няма точен начин за преобразуване на Postgresql заявка в MySQL заявка, но има много заобиколни решения, получената заявка може да е толкова проста като оригиналната или може да стане много сложна, но зависи от самата заявка.