Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我用主键查询的mysql语句有时会返回多行,那么发生了什么?_Mysql - Fatal编程技术网

我用主键查询的mysql语句有时会返回多行,那么发生了什么?

我用主键查询的mysql语句有时会返回多行,那么发生了什么?,mysql,Mysql,我的模式是: CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_name` varchar(10) NOT NULL, `account_type` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 INSERT INTO user VALUES

我的模式是:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(10) NOT NULL,
  `account_type` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1

INSERT INTO user VALUES (1, "zhangsan", "premiumv"), (2, "lisi", "premiumv"), (3, "wangwu", "p"), (4, "maliu", "p"), (5, "hengqi", "p"), (6, "shuba", "p");
表中有以下6行:

+----+-----------+--------------+
| id | user_name | account_type |
+----+-----------+--------------+
|  1 | zhangsan  | premiumv     |
|  2 | lisi      | premiumv     |
|  3 | wangwu    | p            |
|  4 | maliu     | p            |
|  5 | hengqi    | p            |
|  6 | shuba     | p            |
+----+-----------+--------------+
下面是mysql按id查询表:

SELECT * FROM user WHERE id = floor(rand()*6) + 1;
我希望它返回一行,但实际结果是无法预测的。它将返回0行、1行或有时返回多行。有人能帮我澄清一下吗?谢谢

必须为每行计算WHERE部分,以查看是否存在匹配项。因此,对每一行计算rand函数。获取不一致的行数似乎是合理的

如果将LIMIT 1添加到查询中,则从末尾返回行的概率将减小。

这是因为WHERE子句floorrand*6+1将针对表中的每一行进行计算,以查看条件是否符合条件。每次与表中的行匹配时,该值都可能不同

您可以使用在WHERE子句中使用的列中具有相同值的表进行测试,并可以看到结果:

select * from test;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
|    1 | c    |
|    2 | d    |
|    1 | e    |
|    2 | f    |
+------+------+

select * from test where id = floor(rand()*2) + 1;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | d    |
|    1 | e    |
+------+------+

在上面的示例中,表达式floorrand*2+1在与name='a'的第一行匹配时返回1,因此它包含在结果集中。但是,当与第四行name='d'匹配时,它返回2,因此即使id的值与结果集中第一行的值不同,它也会包含在结果集中。

您正在根据不同的随机数测试每一行,因此有时多行会匹配。要解决此问题,请在子查询中计算一次随机数

SELECT u.*
FROM user AS u
JOIN (SELECT floor(rand()*6) + 1 AS r) AS r 
ON u.id = r.r
这种从表中随机选择一行的方法似乎是一种糟糕的设计。如果id序列中存在任何容易出现的间隙,MySQL不能保证它们总是连续的,删除行会留下间隙,那么它可能会返回一个空结果。从表中选择随机行的常用方法是:

SELECT *
FROM user
ORDER BY RAND()
LIMIT 1

我看到使用MariaDB 10.1选择了相同的多行。简单的解决方法是在查询的末尾添加限制1,但我很想知道发生这种情况的原因。