MySQL поиск на основе round(1 + rand() * x) дает NULL и множественные результаты
Я пытаюсь выбрать имена из таблицы поиска случайным образом в MySQL, чтобы создать тестовый набор данных. У меня есть таблица с 200 именами, полами и идентификатором строки от 1 до 200. Примерно так:
id firstname gender
1 Aaron m
2 Adam m
3 Alan m
etc...
Я выбираю из этой таблицы, используя генератор случайных чисел со следующим запросом:
SELECT id, firstname FROM firstname WHERE id = round(1 + (rand() * 199));
Я ожидаю, что случайное число совпадет с ровно одним идентификатором из таблицы поиска, таким образом, получая единичные результаты, такие как
id firstname
43 Jason
Запуск кода снова и снова вместо этого дает мне выбор
- одиночные строки (как указано выше)
- или несколько строк, как
id firstname
29 Ethan
147 Jean
- или нет результатов (просто NULL в обоих полях).
Если я запускаю генератор случайных чисел самостоятельно, он всегда будет генерировать число от 1 до 200. Как вы можете видеть ниже, поле id равно INT, и запрос ведет себя так же, если я приведу результат как SIGNED. Я также попытался использовать FLOOR вместо ROUND, просто чтобы посмотреть, работает ли это по-другому - увы, нет.
Кто-нибудь может рассказать, почему аномалия? Что мне не хватает?
Вот некоторый код для создания первых 20 строк исходной таблицы в целях тестирования:
-- First Name --
drop table if exists firstname;
CREATE TABLE firstname (
id INT NOT NULL,
firstname VARCHAR(20) NOT NULL,
gender VARCHAR(1) NOT NULL,
PRIMARY KEY (id),
UNIQUE (firstname)
);
INSERT INTO firstname
(id,firstname,gender)
VALUES
(1,"Aaron","m"),
(2,"Adam","m"),
(3,"Alan","m"),
(4,"Albert","m"),
(5,"Alexander","m"),
(6,"Andrew","m"),
(7,"Anthony","m"),
(8,"Arthur","m"),
(9,"Austin","m"),
(10,"Benjamin","m"),
(11,"Billy","m"),
(12,"Bobby","m"),
(13,"Brandon","m"),
(14,"Brian","m"),
(15,"Bruce","m"),
(16,"Bryan","m"),
(17,"Carl","m"),
(18,"Charles","m"),
(19,"Christian","m"),
(20,"Christopher","m");
1 ответ
Поскольку RAND()
не является детерминированным, условие WHERE оценивается / выполняется один раз для каждой строки. Таким образом, каждый ряд может быть выбран на 1/199. Вместо этого вы можете использовать подзапрос в предложении FROM (производная таблица), чтобы сгенерировать ровно одно случайное число:
SELECT f.id, f.firstname
FROM firstname f
JOIN (SELECT floor(rand()*200)+1 as rnd) r ON r.rnd = f.id