Jak wspomniano w Wydanie kamienia milowego MySQL 8.0.0 jest dostępny ,
Przypuszczam, że to jest przyczyną zachowania, które obserwuję w nowszych wersjach MySQL. Wspomniana wskazówka może być użyta z MySQL 8.0, aby wymusić wywołanie RAND() tylko raz:
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 |
+---+-----+-----+
Nie jest to jednak dostępne w wersji 5.7. Aby osiągnąć pożądane zachowanie w wersji 5.7, dodaj LIMIT <a very high number>
do definicji tabeli pochodnej (poniżej używam podpisanego LONG_MAX). Dzięki Roy Lyseng za to obejście
.
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 |
+---+-----+-----+
Jako Filipxy wspomniane w komentarzu, wynik wyrażenia zapytania musi być ściśle określony niezależnie od zastosowanych optymalizacji. Co oznacza, że jest to błąd optymalizatora w MySQL 5.7/8.0.