Tidak ada padanan yang tepat untuk mengonversi kueri Postgresql yang menggunakan SELECT DISTINCT ON ke MySQL.
Postgresql PILIH BERBEDA AKTIF
Di Postgresql, kueri berikut akan menghilangkan semua baris di mana ekspresi (col1, col2, col3)
cocok, dan itu hanya akan menyimpan "kolom pertama4, baris kolom5" untuk setiap set baris yang cocok:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
Jadi jika tabel Anda seperti ini:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
kueri kami hanya akan menyimpan satu baris untuk (1,2,3) dan satu baris untuk (3,3,3). Baris yang dihasilkan akan menjadi:
col4 | col5
-----------
777 | 888
555 | 555
harap perhatikan bahwa "baris pertama" dari setiap set tidak dapat diprediksi, baris pertama kami mungkin (888, 999) juga kecuali kami menentukan ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(DISTINCT pada ekspresi harus cocok dengan ekspresi ORDER BY paling kiri, tetapi ORDER BY dapat berisi ekspresi tambahan).
Ekstensi MySQL ke GROUP BY
MySQL memperluas penggunaan GROUP BY sehingga kita dapat memilih kolom non-agregat yang tidak disebutkan dalam klausa GROUP BY. Setiap kali kita memilih kolom yang tidak teragregasi, server bebas memilih nilai apa pun dari setiap grup dari kolom tersebut, sehingga nilai yang dihasilkan tidak akan ditentukan.
Jadi kueri Postgresql ini:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
dapat dianggap setara dengan kueri MySQL ini:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
Postgresql dan MySQL akan mengembalikan "Baris pertama" untuk masing-masing (col1, col2, col3), dan dalam kedua kasus, baris yang dikembalikan tidak dapat diprediksi karena kami tidak menentukan dan mengurutkan berdasarkan klausa.
Banyak orang akan sangat tergoda untuk mengonversi kueri Postgresql ini dengan ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
dengan yang ini:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
idenya di sini adalah untuk menerapkan ORDER BY ke subquery sehingga ketika MySQL mengelompokkan berdasarkan col1, col2, col3 itu akan menyimpan nilai yang ditemui pertama untuk col4 dan col5. Idenya bagus, tapi salah! MySQL bebas memilih nilai apa pun untuk col4 dan col5, dan kami tidak tahu nilai mana yang pertama kali ditemukan, itu tergantung pada pengoptimalnya. Jadi saya akan memperbaikinya menjadi ini:
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
tapi ini mulai menjadi lebih rumit.
Kesimpulan
Sebagai aturan umum, tidak ada cara pasti untuk mengonversi kueri Postgresql ke kueri MySQL, tetapi ada banyak solusi, kueri yang dihasilkan mungkin sesederhana yang asli atau mungkin menjadi sangat rumit, tetapi itu tergantung pada kueri itu sendiri.