У меня два столбца подряд: min_value
, max_value
. Есть ли способ сделать выбор:
SELECT RAND(`min_v`, `max_v`) `foo` [..]
Я понимаю, что RAND
делает другое дело; ближайший я придумал (с помощью) (RAND() * (max-min))+min
, хотя он будет генерировать число с плавающей точкой, которое мне понадобится в ROUND (), и это просто совершенно неправильно.
Если кто-либо не предложит альтернативу (что было бы очень полезно), я пойду PHP.
На самом деле, 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.
Этот метод гарантирует такую же статистическую вероятность для каждого значения:
SELECT FLOOR((RAND() * (max-min+1))+min)
Не могли бы вы сделать что-то подобное?
SELECT id, (FLOOR( 1 + RAND( ) *60 )) AS timer FROM users LIMIT 0 , 30
Посмотреть это сообщение
в случае, если минимальный диапазон равен 1, вы можете просто
SELECT FLOOR((RAND() * max_range) + 1)
в случае, если минимальный диапазон равен 0, вы можете еще проще
SELECT FLOOR((RAND() * max_range))