我想创建一个数据库函数,从数据库表中返回随机行。
我有下表
create table category
(
id bigint not null primary key,
color varchar(255) null
);
我创建了一个函数:
DELIMITER //
create or replace function random_category() returns int
begin
return (select cc.id from category cc order by rand() limit 1);
end //
DELIMITER ;
当调用select random_category();
时,我总是得到一个结果。
但是打电话的时候
select * from category c where id = random_category();
我收到空结果、多行结果和单行结果。
我用10.11.3-MariaDB-1:10.11.3+maria~ubu2204
2条答案
按热度按时间0tdrvxhp1#
这不是一个bug,这是预期的行为。
让我们把你的函数移到一个子查询中,让我们使用一个有几个值的序列:
因为我们使用子查询而不是函数,所以EXPLAIN会更详细一些:
UNCACHEABLE SUBQUERY
意味着子查询的结果不能存储在子查询缓存中,并且必须在每次比较时执行。让我们假设在第一次尝试中,子查询返回3、1和1,在第二次尝试中,它返回2、1和3。在第一次尝试中没有匹配(% 1!= 3,2!= 1和3!= 1),而在第二次尝试中3匹配3。
相关子查询(英语:Correlated Subqueries)(维基百科)
为了避免这种情况,您可以将SQL语句更改为
但是
ORDER BY RAND()
非常慢,我建议你阅读Rick James的优秀文章“Fetching random rows from a table”。krugob8w2#
将为每个单独的行单独调用函数。每个调用生成新的单个
id
值。因此输出行的数量会有所不同。必须调用该函数一次。例如,与
你也可以尝试将你的函数定义为DETERMINISTIC:
AFAIR在这种情况下,函数输出被视为常量(它没有参数),并且它应该被调用一次。但我不确定