簡體   English   中英

MySQL 得到兩個值之間的隨機值

[英]MySQL get a random value between two values

我連續有兩列: min_valuemax_value 有沒有辦法像 select 一樣:

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

我確實意識到RAND做了不同的事情。 我想出的最接近的(在幫助下)是(RAND() * (max-min))+min ,盡管它會產生一個浮點數,然后我需要它來 ROUND() ,這是完全錯誤的。

除非有人可以提出替代方案(這將非常有用),否則我將采用 go 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)

如果最小范圍為 1,您可以簡單地

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


如果最小范圍是 0,你可以更簡單

SELECT FLOOR((RAND() * max_range))

你能做這樣的事情嗎?

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

看到這個帖子

根據表中有多少行,在查詢或子查詢中使用 rand() 可能會非常慢。

您可以通過首先將隨機值放入變量中然后在查詢中使用它來顯着提高速度。

例如在有超過 400 萬行的表上......

這花了 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 或任何地方調用存儲過程

您可以按 rand 使用 order

SELECT virtual.num
FROM (
         SELECT 1 AS num UNION
         SELECT 2 AS num UNION
         SELECT 3 AS num
     ) virtual
ORDER BY RAND()
LIMIT 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM