我用主键查询的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,但我很想知道发生这种情况的原因。