Почему этот запрос MySQL с использованием rand () не возвращает результатов примерно в треть?

У меня есть таблица itemproperties , из которой я хочу захватить случайную itemproperty , однако я хочу, чтобы случайность ее больше ориентировалась на некоторые свойства товара, чем другие.

Для этого я установил столбец « редкость», в котором хранится информация о том, как часто этот элемент должен отображаться (более высокий = чаще), а один называется rarity_position , который настроен с использованием этого запроса:

SET @i:=0;UPDATE itemproperty SET rarity_position = @i:=@i+rarity; 

Это дает следующие результаты:

редкость

Затем, чтобы захватить случайное значение, я подумал, что буду использовать:

 SELECT * FROM itemproperty WHERE id = ( SELECT id FROM itemproperty WHERE rarity_position >= FLOOR ( RAND()* ( SELECT MAX(rarity_position) FROM itemproperty ) ) ORDER BY rarity_position ASC LIMIT 1 ) LIMIT 1 

Чтобы выбрать случайное число с максимальным значением rarity_position, возьмите itemproperty с rarity_position, которое находится чуть выше этого.

В большинстве случаев это работает так, как ожидалось, однако примерно в третий раз результаты не возвращаются.

Возможно, соответствующая информация о сервере:

 Software: MySQL Software version: 5.0.95-log - MySQL Community Server (GPL) Protocol version: 10 Server charset: UTF-8 Unicode (utf8) 

Вы можете воспроизвести поведение этой модели:

 create table itemproperty ( id int, rarity int, rarity_position int ); insert into itemproperty values ( 1, 50, 50 ), ( 2, 50, 100 ), ( 3, 50, 150 ), ( 4, 50, 200 ), ( 5, 50, 250 ), ( 6, 50, 270 ), ( 7, 50, 320 ), ( 8, 50, 370 ), ( 9, 50, 420 ), ( 10, 50, 470 ), ( 11, 50, 520 ) ; 

Если вы пытаетесь выполнить только подзапрос, он работает каждый раз:

  SELECT id FROM itemproperty WHERE rarity_position >= FLOOR ( RAND()* ( SELECT MAX(rarity_position) FROM itemproperty ) ) ORDER BY rarity_position ASC LIMIT 1 

Но если вы инкапсулируете его в:

 SELECT * FROM itemproperty WHERE id = ( // here the above request ) LIMIT 1; 

Он не будет работать так, как ожидалось.

Что заставляет его не возвращать никаких результатов каждый раз?

 SELECT * FROM itemproperty ORDER BY RAND() * rarity DESC LIMIT 1 

Нашел работоспособное решение, подобное методу zerkms:

 ORDER BY -LOG(1.0 – RAND()) / rarity 

Источник

Примечательно, что недостающие части выглядят так, как будто они могут быть связаны с этим вопросом: запрос MySQL с условием подзапроса RAND ()

Я предполагаю, что RAND () в ГДЕ вызывает некоторую странность.