У меня есть две таблицы. В одной таблице id
пользователей, в другой id
пользователей, которых функция рандома не должна вызвать. Надо вывести 3 рандомных не повторяющихся числа из переменной $allowed
.
$banned = "SELECT id FROM admin";
$allowed = "SELECT id FROM 10a WHERE id NOT IN (". $banned .")";
Простейший вариант, который судя по названию таблицы 10a
(школа?), Вам подойдёт:
SELECT id
FROM 10a
WHERE id NOT IN (SELECT id FROM admin)
ORDER BY RAND()
LIMIT 3
Недостаток этого варианта - логарифмическое замедление при увеличении количества строк в таблице 10a
, так как ORDER BY RAND()
вызывает сканирование и затем сортировку всей таблицы целиком - и без использования индексов.
Вот здесь и здесь всё это неплохо расписано.
Вариант для больших таблиц, который мне кажется предпочтительным, это вставка в таблицу дополнительного индексированного float
столбца rnd
, в который при создании строки записывается результат функции RAND()
. В этом случае рандомизация выполняется на этапе заполнения таблицы, а при выборке мы случайным образом определяем начальное значение столбца rnd
и выполняем чтение нужного количества строк, отсортированных по rnd
.
Пример на db-fiddle. Схемы таблиц и запрос - ниже:
CREATE TABLE 10a (
id INT NOT NULL AUTO_INCREMENT,
name text,
rnd float,
PRIMARY KEY (id)
);
CREATE TABLE admin (
id INT
);
CREATE TRIGGER 10a_bi
BEFORE INSERT ON 10a
FOR EACH ROW
SET NEW.rnd = RAND();
CREATE INDEX rnd_idx ON 10a(rnd);
Заметьте, что в запросе 2 раза встречается число 3 - количество возвращаемых значений. Это сделано для того, чтобы "неудачники" с 3 самыми большими значениями rnd
имели равновероятный шанс попасть в выдачу, как и все остальные
SELECT r.*
FROM
(
SELECT RAND() *
(
SELECT rnd
FROM 10a
WHERE id NOT IN (SELECT id FROM admin)
ORDER BY rnd DESC
LIMIT 1 OFFSET 3
) start
) init
JOIN 10a r
WHERE r.rnd > init.start
AND id NOT IN (SELECT id FROM admin)
ORDER BY r.rnd
LIMIT 3;
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
День добрый! Не могу понять почему при выводе на экран всей строки отображается как должно, а при переборе �? Подскажите в чем дело
Нужно чтобы в заявке с формы отображалось ключевое слово, по которому пользователь перешел на сайтКто-нибудь знает как реализовать? Обработчик...
Что лучше использовать для решения таких задач в PHP (mysqL):