Jelek, tapi cepat dan acak. Bisa menjadi sangat jelek dengan sangat cepat, terutama dengan penyetelan yang dijelaskan di bawah ini, jadi pastikan Anda benar-benar menginginkannya dengan cara ini.
(SELECT Products.ID, Products.Name
FROM Products
INNER JOIN (SELECT RAND()*(SELECT MAX(ID) FROM Products) AS ID) AS t ON Products.ID >= t.ID
WHERE Products.HasImages=1
ORDER BY Products.ID
LIMIT 1)
UNION ALL
(SELECT Products.ID, Products.Name
FROM Products
INNER JOIN (SELECT RAND()*(SELECT MAX(ID) FROM Products) AS ID) AS t ON Products.ID >= t.ID
WHERE Products.HasImages=1
ORDER BY Products.ID
LIMIT 1)
UNION ALL
(SELECT Products.ID, Products.Name
FROM Products
INNER JOIN (SELECT RAND()*(SELECT MAX(ID) FROM Products) AS ID) AS t ON Products.ID >= t.ID
WHERE Products.HasImages=1
ORDER BY Products.ID
LIMIT 1)
Baris pertama muncul lebih sering dari yang seharusnya
Jika Anda memiliki celah besar antara ID di tabel Anda, baris tepat setelah celah tersebut akan memiliki peluang lebih besar untuk diambil oleh kueri ini. Dalam beberapa kasus, mereka akan muncul secara signifikan lebih sering dari yang seharusnya. Ini tidak dapat diselesaikan secara umum, tetapi ada perbaikan untuk kasus khusus yang umum:ketika ada celah antara 0 dan ID pertama yang ada dalam sebuah tabel.
Alih-alih subquery (SELECT RAND()*<max_id> AS ID)
gunakan sesuatu seperti (SELECT <min_id> + RAND()*(<max_id> - <min_id>) AS ID)
Hapus duplikat
Kueri, jika digunakan apa adanya, dapat mengembalikan baris duplikat. Dimungkinkan untuk menghindarinya dengan menggunakan UNION
bukannya UNION ALL
. Dengan cara ini duplikat akan digabungkan, tetapi kueri tidak lagi menjamin untuk mengembalikan tepat 3 baris. Anda juga dapat mengatasinya, dengan mengambil lebih banyak baris daripada yang Anda butuhkan dan membatasi hasil luar seperti ini:
(SELECT ... LIMIT 1)
UNION (SELECT ... LIMIT 1)
UNION (SELECT ... LIMIT 1)
...
UNION (SELECT ... LIMIT 1)
LIMIT 3
Namun, masih belum ada jaminan bahwa 3 baris akan diambil. Itu hanya membuatnya lebih mungkin.