Py学习  »  DATABASE

为什么我的MySQL程序应该选择一个随机行,而只选择三个特定值中的一个?

just_another_question • 3 年前 • 1306 次点击  

我有一个名为 quote_of_the_day 它应该从列表中选择不同的行 quotes 表中的日期作为种子值。当我将代码作为查询进行测试时,一切似乎都运行良好,但当我在php代码中调用函数时(查询是 CALL quote_of_the_day() )它只会从三个不同的引号中选择一个,尽管表中有23个引号。

创建systax for 引用今天的话 是:

DELIMITER ;;
CREATE DEFINER=`root`@`%` PROCEDURE `quote_of_the_day`()
BEGIN
        # save the number of rows into a variable
        SET @num_rows = (SELECT COUNT(*) FROM `quotes`);

        # calculate a random number no greater than the number of rows in the table
        SET @rand_num = (SELECT FLOOR(RAND(CURDATE())*(@num_rows+1)));

        # select random quote from the list of quotes (seed value is the current day)
        SELECT quote FROM quotes WHERE id = @rand_num;
        
        # increment the quoted column to keep track of which quotes are selected
        UPDATE quotes SET quoted = quoted + 1 WHERE id = @rand_num AND last_used <> CURDATE();
        UPDATE quotes SET last_used = CURDATE() WHERE id = @rand_num;
    END;;
DELIMITER ;

我哪里做错了?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/127950
 
1306 次点击  
文章 [ 2 ]  |  最新文章 3 年前
Bohemian
Reply   •   1 楼
Bohemian    3 年前

您的seed在日期的年份保持不变,因为当MySQL将字符串转换为日期时,它使用它在字符串中找到的第一个数字字符串,该字符串当前为 2021 .

使用 TO_DAYS() 种子 RAND() 自去年以来的天数 0 :

RAND(TO_DAYS(CURDATE()))

每一天都将永远传递一个不同的、但在当前日期不变的值 rand()

Bill Karwin
Reply   •   2 楼
Bill Karwin    3 年前

上面的评论是在用答案取笑你。

请阅读MySQL上的手册 RAND() function :

...对于相等的参数值,RAND(N)每次返回相同的值,从而生成一个可重复的列值序列。在下面的示例中,RAND(3)生成的值序列在两个位置都是相同的。

由于CURDATE()在同一天内每次调用时都返回一个常量值,因此将其传递给RAND()会使RAND()在每次调用时都返回相同的值。

演示:

mysql> select rand(curdate());
+------------------+
| rand(curdate())  |
+------------------+
| 0.49455075570806 |
+------------------+
1 row in set (0.00 sec)

mysql> select rand(curdate());
+------------------+
| rand(curdate())  |
+------------------+
| 0.49455075570806 |
+------------------+
1 row in set (0.00 sec)

mysql> select rand(curdate());
+------------------+
| rand(curdate())  |
+------------------+
| 0.49455075570806 |
+------------------+
1 row in set (0.00 sec)

mysql> select rand(curdate());
+------------------+
| rand(curdate())  |
+------------------+
| 0.49455075570806 |
+------------------+
1 row in set (0.00 sec)

这将一直持续到我的时钟显示这是新的一天。

实际上不需要将值传递给seed RAND()。当MySQL服务器启动时,它会得到一个种子,并继续生成随机值。

当需要一系列新的随机值时,不要使用seed参数,当需要 可复制的随机值序列 ,例如,如果您正在运行自动测试。


请回复您的评论:

RAND()的参数是一个整数,但像“2021-11-07”这样的日期将作为字符串返回。在数值上下文中,“2021-11-07”的整数值为2021。任何非数字字符在作为参数传递给RAND()之前都会被去除。

mysql> select rand('2021-11-04');
+--------------------+
| rand('2021-11-04') |
+--------------------+
| 0.7752841103591808 |
+--------------------+
1 row in set, 1 warning (0.00 sec)

mysql> select rand('2021-11-05');
+--------------------+
| rand('2021-11-05') |
+--------------------+
| 0.7752841103591808 |
+--------------------+
1 row in set, 1 warning (0.00 sec)

mysql> select rand('2021-11-06');
+--------------------+
| rand('2021-11-06') |
+--------------------+
| 0.7752841103591808 |
+--------------------+
1 row in set, 1 warning (0.00 sec)

mysql> select rand('2021-11-07');
+--------------------+
| rand('2021-11-07') |
+--------------------+
| 0.7752841103591808 |
+--------------------+
1 row in set, 1 warning (0.00 sec)

你可以看到它是这样做的:

mysql> show warnings;
+---------+------+-------------------------------------------------+
| Level   | Code | Message                                         |
+---------+------+-------------------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: '2021-11-07' |
+---------+------+-------------------------------------------------+

所有这些日期都在播种随机数,好像你只通过了“2021”或2021作为参数:

mysql> select rand('2021');
+--------------------+
| rand('2021')       |
+--------------------+
| 0.7752841103591808 |
+--------------------+
1 row in set (0.00 sec)

mysql> select rand(2021);
+--------------------+
| rand(2021)         |
+--------------------+
| 0.7752841103591808 |
+--------------------+
1 row in set (0.00 sec)