Както е посочено в Изданието на MySQL 8.0.0 Milestone е наличен ,
Предполагам, че това е причината за поведението, което наблюдавам в по-новите версии на MySQL. Споменатият намек може да се използва с MySQL 8.0, за да принуди RAND() да бъде извикан само веднъж:
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 |
+---+-----+-----+
Това обаче не е налично в 5.7. За да постигнете желаното поведение с 5.7, добавете LIMIT <a very high number>
към дефиницията на извлечената таблица (използвам подписан LONG_MAX по-долу). Благодаря на Roy Lyseng за това заобикаляне
.
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 |
+---+-----+-----+
Като philipxy споменат в коментара, резултатът от израз на заявка трябва да бъде строго дефиниран, независимо от приложените оптимизации. Което означава, че е грешка в оптимизатора в MySQL 5.7/8.0.