按不同字段值随机选择一行


Select random row per distinct field value?

我有一个MySQL查询,结果如下:

person | some_info 
==================
   bob | pphsmbf24
   bob | rz72nixdy
   bob | rbqqarywk
  john | kif9adxxn
  john | 77tp431p4
  john | hx4t0e76j
  john | 4yiomqv4i
  alex | n25pz8z83
  alex | orq9w7c24
  alex | beuz1p133
   etc...

(这只是一个简化的例子。实际上,我的结果中大约有5000行)。

我需要做的是浏览列表中的每个人(bob、john、alex等),并从他们的一组结果中抽出一行。我抽出的那一排有点随机,但也有点基于一组松散的条件。在这里指定条件并不重要,所以我只说这是一个随机行。

无论如何,使用PHP,这个解决方案非常简单。我进行查询,返回5000行,并对它们进行迭代,为每个人提取我的随机行。容易的

然而,我想知道是否有可能只从MySQL查询中获得我想要的结果,这样我就不必使用PHP来迭代结果并提取我的随机行。

我有一种感觉,它可能涉及一堆子选项,比如每个人一个,在这种情况下,该解决方案将比我当前的解决方案更耗费时间、资源和带宽。

有没有一个聪明的查询可以在一个命令中完成这一切?

这里有一个你可以玩的SQLFiddle。

要获得不同名称的随机值,请使用

SELECT r.name, 
(SELECT r1.some_info FROM test AS r1 WHERE r.name=r1.name ORDER BY rand() LIMIT 1) AS     'some_info' 
FROM test AS r 
GROUP BY r.name ;  

把这个查询放在sqlfiddle中,它就会在中工作

我使用r和r1作为表别名。这也将使用子查询为名称选择一个随机的some_info

SQL Fiddle在这里

我的第一个响应是使用php生成一个随机数:

$randId=兰特($min,$max);

然后运行SQL查询,该查询只获取索引等于$randID的记录。

以下是解决方案:

select person, acting from personel where id in (
select lim from 
    (select count(person) c, min(id) i, cast(rand()*(count(person)-1) +min(id)
             as unsigned) lim from personel group by person order by i) t1
)

示例中使用的表格如下:

create table personel (
id int(11) not null auto_increment,
person char(16),
acting char(19),
primary key(id)

);

insert into personel (person,acting) values
('john','abd'),('john','aabd'),('john','adbd'),('john','abfd'),
('alex','ab2d'),('alex','abd3'),('alex','ab4d'),('alex','a6bd'),
('max','ab2d'),('max','abd3'),('max','ab4d'),('max','a6bd'),
('jimmy','ab2d'),('jimmy','abd3'),('jimmy','ab4d'),('jimmy','a6bd');

您可以限制查询次数,并通过"rand()"排序以获得所需结果。

也许如果你尝试这样的东西:

SELECT name, some_info
  FROM test
 WHERE name = 'tara'
 ORDER BY rand()
 LIMIT 1