此查询如何返回超过 1 行?
SELECT username FROM phpbb_users WHERE user_id = (SELECT (FLOOR(RAND() * (5050 - 50 + 1)) + 50));
Run Code Online (Sandbox Code Playgroud)
表元:
CREATE TABLE `phpbb_users` (
`user_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`user_type` tinyint(2) NOT NULL DEFAULT '0',
`group_id` mediumint(8) unsigned NOT NULL DEFAULT '3',
`user_permissions` mediumtext COLLATE utf8_bin NOT NULL,
`user_perm_from` mediumint(8) unsigned NOT NULL DEFAULT '0',
`user_ip` varchar(40) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_regdate` int(11) unsigned NOT NULL DEFAULT '0',
`username` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`username_clean` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_password` varchar(40) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_passchg` int(11) unsigned NOT NULL DEFAULT '0',
`user_pass_convert` tinyint(1) unsigned NOT NULL DEFAULT '0',
`user_email` varchar(100) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_email_hash` bigint(20) NOT NULL DEFAULT '0',
`user_birthday` varchar(10) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_lastvisit` int(11) unsigned NOT NULL DEFAULT '0',
`user_lastmark` int(11) unsigned NOT NULL DEFAULT '0',
`user_lastpost_time` int(11) unsigned NOT NULL DEFAULT '0',
`user_lastpage` varchar(200) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_last_confirm_key` varchar(10) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_last_search` int(11) unsigned NOT NULL DEFAULT '0',
`user_warnings` tinyint(4) NOT NULL DEFAULT '0',
`user_last_warning` int(11) unsigned NOT NULL DEFAULT '0',
`user_login_attempts` tinyint(4) NOT NULL DEFAULT '0',
`user_inactive_reason` tinyint(2) NOT NULL DEFAULT '0',
`user_inactive_time` int(11) unsigned NOT NULL DEFAULT '0',
`user_posts` mediumint(8) unsigned NOT NULL DEFAULT '0',
`user_lang` varchar(30) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_timezone` decimal(5,2) NOT NULL DEFAULT '0.00',
`user_dst` tinyint(1) unsigned NOT NULL DEFAULT '0',
`user_dateformat` varchar(30) COLLATE utf8_bin NOT NULL DEFAULT 'd M Y H:i',
`user_style` mediumint(8) unsigned NOT NULL DEFAULT '0',
`user_rank` mediumint(8) unsigned NOT NULL DEFAULT '0',
`user_colour` varchar(6) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_new_privmsg` int(4) NOT NULL DEFAULT '0',
`user_unread_privmsg` int(4) NOT NULL DEFAULT '0',
`user_last_privmsg` int(11) unsigned NOT NULL DEFAULT '0',
`user_message_rules` tinyint(1) unsigned NOT NULL DEFAULT '0',
`user_full_folder` int(11) NOT NULL DEFAULT '-3',
`user_emailtime` int(11) unsigned NOT NULL DEFAULT '0',
`user_topic_show_days` smallint(4) unsigned NOT NULL DEFAULT '0',
`user_topic_sortby_type` varchar(1) COLLATE utf8_bin NOT NULL DEFAULT 't',
`user_topic_sortby_dir` varchar(1) COLLATE utf8_bin NOT NULL DEFAULT 'd',
`user_post_show_days` smallint(4) unsigned NOT NULL DEFAULT '0',
`user_post_sortby_type` varchar(1) COLLATE utf8_bin NOT NULL DEFAULT 't',
`user_post_sortby_dir` varchar(1) COLLATE utf8_bin NOT NULL DEFAULT 'a',
`user_notify` tinyint(1) unsigned NOT NULL DEFAULT '0',
`user_notify_pm` tinyint(1) unsigned NOT NULL DEFAULT '1',
`user_notify_type` tinyint(4) NOT NULL DEFAULT '0',
`user_allow_pm` tinyint(1) unsigned NOT NULL DEFAULT '1',
`user_allow_viewonline` tinyint(1) unsigned NOT NULL DEFAULT '1',
`user_allow_viewemail` tinyint(1) unsigned NOT NULL DEFAULT '1',
`user_allow_massemail` tinyint(1) unsigned NOT NULL DEFAULT '1',
`user_options` int(11) unsigned NOT NULL DEFAULT '230271',
`user_avatar` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_avatar_type` tinyint(2) NOT NULL DEFAULT '0',
`user_avatar_width` smallint(4) unsigned NOT NULL DEFAULT '0',
`user_avatar_height` smallint(4) unsigned NOT NULL DEFAULT '0',
`user_sig` mediumtext COLLATE utf8_bin NOT NULL,
`user_sig_bbcode_uid` varchar(8) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_sig_bbcode_bitfield` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_from` varchar(100) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_icq` varchar(15) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_aim` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_yim` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_msnm` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_jabber` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_website` varchar(200) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_occ` text COLLATE utf8_bin NOT NULL,
`user_interests` text COLLATE utf8_bin NOT NULL,
`user_actkey` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_newpasswd` varchar(40) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_form_salt` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
`user_new` tinyint(1) unsigned NOT NULL DEFAULT '1',
`user_reminded` tinyint(4) NOT NULL DEFAULT '0',
`user_reminded_time` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`user_id`),
UNIQUE KEY `username_clean` (`username_clean`),
KEY `user_birthday` (`user_birthday`),
KEY `user_email_hash` (`user_email_hash`),
KEY `user_type` (`user_type`)
) ENGINE=InnoDB AUTO_INCREMENT=5056 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
Run Code Online (Sandbox Code Playgroud)
ype*_*eᵀᴹ 11
原因是WHERE
条件:
WHERE user_id = (SELECT (FLOOR(RAND() * (5050 - 50 + 1)) + 50))
Run Code Online (Sandbox Code Playgroud)
每行评估一次。因此,对于每一行,都会进行一次新的调用RAND()
,因此查询可以返回 0、1、2、3 或更多行。查询有可能(尽管非常小)返回表的所有行!
与DELETE
语句类似的问题,其中调用RAND()
在ORDER BY
子句中:MySQL subquery 的问题
如果您希望查询永远不会返回超过 1 行,您可以在查询之前评估随机数,因此RAND()
调用一次:
SET @random_number = FLOOR(RAND() * (5050 - 50 + 1)) + 50 ;
SELECT username FROM phpbb_users WHERE user_id = @random_number ;
Run Code Online (Sandbox Code Playgroud)
正如@a1ex07 提到的,您还可以使用派生表:
SELECT u.username
FROM
(SELECT FLOOR(RAND() * (5050 - 50 + 1)) + 50 AS random_number) AS r
JOIN
phpbb_users AS u
ON u.user_id = r.random_number ;
Run Code Online (Sandbox Code Playgroud)
不过作为一个警告,我找不到有关此行为的任何文档,因此它很可能在未来版本中发生变化(仅在 5.1 和 5.5 版本中测试。)版本 5.6、5.7 和 MariaDB(5.1、 5.3+) 可能已经改变了这种行为。