Selecione a linha aleatória por valor de campo distinto?

Eu tenho uma consulta MySQL que resulta em algo como isto:

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

(Este é apenas um exemplo simplificado. Na realidade, existem cerca de 5000 linhas em meus resultados).

O que eu preciso fazer é passar por cada pessoa na lista (bob, john, alex, etc …) e retirar uma linha de seu conjunto de resultados. A linha que eu retiro é uma espécie de aleatória, mas também baseada em um conjunto de condições. Não é importante especificar as condições aqui, então eu vou dizer que é uma linha aleatória para o exemplo.

De qualquer forma, usando PHP, esta solução é bastante simples. Eu faço minha consulta e obtenho 5000 linhas de volta e iterei através delas retirando minha linha aleatória para cada pessoa. Fácil.

No entanto, eu estou me perguntando se é possível obter o que eu faria apenas de uma consulta MySQL para que eu não precise usar o PHP para iterar através dos resultados e retirar minhas linhas aleatórias.

Tenho a sensação de que pode envolver um BUNCH de subselects, como um para cada pessoa, caso em que essa solução seria mais tempo, resources e largura de banda intensivos do que a minha solução atual.

Existe uma consulta inteligente que pode realizar isso tudo em um comando?

Aqui está um SQLFiddle com o qual você pode jogar.

Para obter um valor random para um nome distinto use

 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 ; 

Coloque esta consulta como está em seu sqlfiddle e funcionará

Estou usando r e r1 como nomes de alias de tabelas. Isso também usará uma subconsulta para selecionar random some_info para o nome

SQL Fiddle está aqui

Você pode limitar o número de consultas e pedir por “rand ()” para obter o resultado desejado.

Talvez se você tentar algo como isto:

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

Minha primeira resposta seria usar php para gerar um número random:

$ randId = rand ($ min, $ max);

Em seguida, execute uma consulta SQL que apenas obtenha o registro onde seu índice é igual a $ randID.

Aqui está a solução:

 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 ) 

A tabela usada no exemplo está abaixo:

 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');