Seperti disebutkan dalam Rilis Milestone MySQL 8.0.0 tersedia ,
Saya kira ini adalah penyebab perilaku yang saya amati di versi MySQL yang lebih baru. Petunjuk yang disebutkan dapat digunakan dengan MySQL 8.0 untuk memaksa RAND() dipanggil hanya sekali:
SELECT /* NO_MERGE(q) */
q.i,
q.r,
q.r
FROM (
SELECT
id AS i,
(FLOOR(RAND(100) * 4)) AS r
FROM t
) AS q;
+---+-----+-----+
| i | r | r |
+---+-----+-----+
| 1 | 0 | 0 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 2 | 2 |
| 5 | 1 | 1 |
+---+-----+-----+
Namun ini tidak tersedia di 5.7. Untuk mencapai perilaku yang diinginkan dengan 5.7, tambahkan LIMIT <a very high number>
ke definisi tabel turunan (saya menggunakan LONG_MAX yang ditandatangani di bawah). Terima kasih kepada Roy Lyseng untuk solusi
ini .
SELECT
q.i,
q.r,
q.r
FROM (
SELECT
id AS i,
(FLOOR(RAND(100) * 4)) AS r
FROM t LIMIT 9223372036854775807
) AS q;
+---+-----+-----+
| i | r | r |
+---+-----+-----+
| 1 | 0 | 0 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 2 | 2 |
| 5 | 1 | 1 |
+---+-----+-----+
Sebagai philipxy disebutkan dalam komentar, hasil ekspresi kueri harus ditentukan secara ketat terlepas dari pengoptimalan apa pun yang diterapkan. Artinya, ini adalah bug pengoptimal di MySQL 5.7/8.0.