Добре.
Ось код.
SELECT t.*
FROM
(SELECT
ROUND(RAND() * ((SELECT MAX(id) FROM myTable)-100))+100 num,
@num:=@num+1
FROM
(SELECT @num:=0) AS a,
myTable LIMIT 6) AS b,
myTable AS t
WHERE b.num = t.id AND t.xFactor='Q';
Важкість завдання:
Його важкість в тому, що код має вибірку декількох рандомних рядків, тобто умова змінюється кожного разу коли випадає нове число. З новим рандомним числом оновлюється перехід до реально-існуючого стовпчика. і так робить не одну вибірку а декілька разів! тому що умова змінюється в середині одного ЗАПИТУ кожного разу!
Тобто рандом! - не статична вибірка! Оо , ... її просто так не вкладеш в аби яку частину коду.
Код працює дуже швидко навіть в великих таблицях.
Дійсно шукає випадкові комірки а не підряд "згідно шаблонів"
В таблиці кожен ряд має сортоване/не сортоване значення ID (індексоване, а тому і унікальне)
Значення ID може мати пропуски, а тому вибірка, не знайшовши рядок ID по умові-рандому, виконує новий пошук, доти вихідна таблиця не набере необхідну кількість вибраних рядків.
Проблеми завдання: - з якими я вже зіткнувся, треба вирішувати ...
- не використовувати самий простий запит типу SELECT * FROM myTable ORDER BY RAND() LIMIT 1; , а вдосконалити! наданий вище код (чи пропонувати інший, контрольований умовами коду, не втрачаючи імовірну швидкість пошуку).
- вищевказаний приклад, не перевіряє, якщо рандом випадково двічі обере, один і той самий рядок в вихідну таблицю.
- Чим менше кількість рядків в таблиці пошуку (донору) - тим більше вірогідність що 2 чи 3 рази нам буде показаний однаковий рядок. І тоді фільтрування типу GROUP BY, або SELECT DISTINCT у вищевказаному прикладі! - просто зменшить кількість рядків на виході опісля їх отримання. Ми не виконаємо тоді умову, що нам потрібна "X-кількість" рядків а не "X" мінус фільтр.
Треба:
- кожен рядок рандомно вирахуваний з таблиці
- кожен рядок не однаковий на виході, з аби яким іншим (імовірність однакових полів не повинна трапитись)
- рядків рівно стільки як треба, наприклад 6-ть (шість). І якщо шість у завданні, то не п'ять, не чотири на виході.
- реляційний запит
- таблиця-донор з 500.000 - 1.000.000 рядків. Тобто не можна просто так робити зайві пошукові операції.
Ось тому я поки що теоретично маю вихід:
Використання додаткової тимчасової таблиці CREATE TEMPORARY ...
- коли треба, додам рядок (з перевіркою або без, на однаковість, краще не робити тут перевірку)
- коли треба (якщо треба) порівняю нове отримане рандом-число з тимчасовою таблицею на співпадіння і одночасно перевірка з рядком таблиці-донора
P.S. Може у вас інший варіант чи натяк на методику?
P.P.S. цей текст потім продублюю в свою тему про рандом, затримуюсь ... там ще не виклав деякі результати інших рандом-рішень. Цей приклад буде кінцевим.