Подтвердить что ты не робот

MySQL получает случайное значение между двумя значениями

У меня есть два столбца подряд: min_value, max_value. Есть ли способ сделать выбор:

SELECT RAND(`min_v`, `max_v`) `foo` [..]

Я понимаю, что RAND делает другую вещь; ближайший я придумал (с помощью) (RAND() * (max-min))+min, хотя он будет генерировать число с плавающей точкой, которое мне понадобится в ROUND(), и это просто совершенно неправильно.

Если кто-либо может предложить альтернативу (что было бы очень полезно), я пойду PHP.

4b9b3361

Ответ 1

На самом деле, ROUND((RAND() * (max-min))+min) - лучший способ в MySQL сделать то, что вы хотите. Это также лучший способ в ActionScript, JavaScript и Python. Честно говоря, я предпочитаю его PHP-способу, потому что это более удобно.

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

Добавление


Итак, возник вопрос о том, лучше ли это в PHP или MySQL. Вместо того, чтобы вступать в дискуссию о принципах, я запускал следующее:

<pre><?php

$c = mysql_connect('localhost', 'root', '');

if(!$c) die('!');
echo mysql_select_db('test', $c)?'Connection':'Failure';
echo PHP_EOL;

echo ':::::::::::::::::::::::::BEGINNING MYSQL RAND::::::::::::::::::::::::::::::'.PHP_EOL;
$start = microtime(1);
for( $i = 0; $i < 100000; $i++ )
{
    $r = mysql_query( 'SELECT ROUND(RAND() * (200-10) + 10) FROM dual' );
    $r = mysql_fetch_array( $r );
}
$end = microtime(1);

echo  ($end - $start) . " for MySQL select".PHP_EOL;

echo ':::::::::::::::::::::::::BEGINNING PHP RAND::::::::::::::::::::::::::::::' .PHP_EOL;
$start = microtime(1);
for( $i = 0; $i < 100000; $i++ )
{
    $r = mysql_query( 'SELECT 200 AS two, 10 AS tem FROM dual' );
    $r = mysql_fetch_array( $r );
    $r[2]= rand($r[0], $r[1]);
}
$end = microtime(1);

echo  ($end - $start) . " for PHP select".PHP_EOL;

MySQL быстрее примерно на 2-3%.

Если вы используете это, однако (обратите внимание, больше столбцов возвращается MySQL):

<pre><?php

$c = mysql_connect('localhost', 'root', '');

if(!$c) die('!');
echo mysql_select_db('test', $c)?'Connection':'Failure';
echo PHP_EOL;

echo ':::::::::::::::::::::::::BEGINNING MYSQL RAND::::::::::::::::::::::::::::::'.PHP_EOL;
$start = microtime(1);
for( $i = 0; $i < 100000; $i++ )
{
    $r = mysql_query( 'SELECT ROUND(RAND() * (200-10) + 10) as rd, 200 as two, 10 as ten FROM dual' );
    $r = mysql_fetch_array( $r );
}
$end = microtime(1);

echo  ($end - $start) . " for MySQL select".PHP_EOL;

echo ':::::::::::::::::::::::::BEGINNING PHP RAND::::::::::::::::::::::::::::::' .PHP_EOL;
$start = microtime(1);
for( $i = 0; $i < 100000; $i++ )
{
    $r = mysql_query( 'SELECT 200 AS two, 10 AS tem FROM dual' );
    $r = mysql_fetch_array( $r );
    $r[2]= rand($r[0], $r[1]);
}
$end = microtime(1);

echo  ($end - $start) . " for PHP select".PHP_EOL;

MySQL отстает на 3-4% (очень непоследовательные результаты) (примерно такие же результаты, если вы не используете назначение индекса массива для $r [2]).

Основное отличие, по-видимому, связано с количеством записей, возвращаемых PHP, а не самой системой рандомизации. Итак, если вам нужен столбец A, столбец B и случайное значение, используйте PHP. Если вам нужно только случайное значение, используйте MySQL.

Ответ 2

Этот метод гарантирует такую ​​же статистическую вероятность для каждого значения:

SELECT FLOOR((RAND() * (max-min+1))+min)

Ответ 3

Не могли бы вы сделать что-то вроде этого?

SELECT id, (FLOOR( 1 + RAND( ) *60 )) AS timer
FROM users
LIMIT 0 , 30

См. этот пост

Ответ 4

если минимальный диапазон равен 1, вы можете просто

SELECT FLOOR((RAND() * max_range) + 1)


в случае, если минимальный диапазон равен 0, вы можете еще проще

SELECT FLOOR((RAND() * max_range))

Ответ 5

В зависимости от того, сколько строк в таблице (ах), использование rand() в запросе или подзапросе может быть очень медленным.

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

Например, для таблицы с более чем 4 миллионами строк...

Это заняло более 10 минут:

SELECT
    *
FROM
    'customers' 'Customer'
WHERE
    'id' = (
        SELECT
            FLOOR((RAND() * (max('CustomerRand'.'id') - min('CustomerRand'.'id') + 1)) + min('CustomerRand'.'id')) 'random_id'
        FROM
            'customers' 'CustomerRand'
    );

Хотя на это уходит в среднем около 3 секунд:

SELECT
   FLOOR((RAND() * (max('CustomerRand'.'id') - min('CustomerRand'.'id') + 1)) + min('CustomerRand'.'id')) 'random_id'
FROM 'customers' 'CustomerRand' INTO @rand_id;

SELECT * FROM 'customers' WHERE 'id' = @rand_id;

Возможно, вы даже сможете поместить это в хранимую процедуру, если это то, что вы захотите сделать или использовать повторно часто. Затем хранимая процедура может быть вызвана из PHP или Python или где угодно