У меня есть таблица MySQL с набором записей в нем и столбца под названием "Множитель". Значение по умолчанию (и наиболее распространенный) значение для этого столбца 0, но это могло быть любое число.
То, что я должен сделать, выбрать однократный въезд из той таблицы наугад. Однако строки взвешиваются согласно числу в столбце "Multiplier". Значение 0 средств, что это не взвешивается вообще. Значение 1 средства, что это взвесило вдвое больше, как будто запись была в таблице дважды. Значение 2 средств, что это взвесило в три раза больше, как будто запись была в таблице три раза.
Я пытаюсь изменить то, что мои разработчики уже дали мне, очень жаль если установка не имеет большой смысл. Я мог, вероятно, изменить его, но хотеть сохранить как можно больше существующей установки таблицы.
Я пытался выяснить, как сделать это с ВЫБОРОМ и РЭНДОМ (), но не знайте, как сделать взвешивание. Действительно ли это возможно?
Не используйте 0, 1 и 2, но 1, 2 и 3. Затем вы можете использовать это значение как множитель:
SELECT * FROM tablename ORDER BY (RAND() * Multiplier);
Ну, я бы поместил логику весов в PHP:
<?php
$weight_array = array(0, 1, 1, 2, 2, 2);
$multiplier = $weight_array[array_rand($weight_array)];
?>
и запрос:
SELECT *
FROM `table`
WHERE Multiplier = $multiplier
ORDER BY RAND()
LIMIT 1
Думаю, это сработает :)
Что бы вы ни делали, это ужасно, потому что это потребует: * Получение общего "веса" для всех столбцов как ОДНОГО число (включая применение множителя). * Получение случайного числа от 0 до этой суммы. * Получение всех записей и их обработка, вычитание веса из случайного числа и выбор одной записи, когда у вас заканчиваются элементы.
В среднем вы пробегаете половину стола. Производительность - если таблица не мала, тогда делать это вне mySQL в памяти - будет МЕДЛЕННАЯ.
Результат псевдокода (rand (1, num)% rand (1, num))
будет больше к 0 и меньше к num. Вычтите результат из числа, чтобы получить обратное.
Итак, если моим языком приложения является PHP, он должен выглядеть примерно так:
$arr = mysql_fetch_array(mysql_query(
'SELECT MAX(`Multiplier`) AS `max_mul` FROM tbl'
));
$MaxMul = $arr['max_mul']; // Holds the maximum value of the Multiplier column
$mul = $MaxMul - ( rand(1, $MaxMul) % rand(1, $MaxMul) );
mysql_query("SELECT * FROM tbl WHERE Multiplier=$mul ORDER BY RAND() LIMIT 1");
Объяснение приведенного выше кода:
Это также возможно просто с помощью MySQL.
Доказательство того, что псевдокод (rand (1, num)% rand (1, num))
будет иметь вес в сторону 0:
Выполните следующий PHP-код, чтобы увидеть почему (в этом примере 16 - наибольшее число):
$v = array();
for($i=1; $i<=16; ++$i)
for($k=1; $k<=16; ++$k)
isset($v[$i % $k]) ? ++$v[$i % $k] : ($v[$i % $k] = 1);
foreach($v as $num => $times)
echo '<div style="margin-left:', $times ,'px">
times: ',$times,' @ num = ', $num ,'</div>';