Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MYSQL seleciona 2 linhas aleatórias de cada categoria


Basta buscar 2 por categoria como você descreveu e um aleatório no final. Não é uma consulta, mas um conjunto de resultados, que pode ser o que você precisa:
SELECT * FROM (SELECT * FROM questions WHERE category= 1 ORDER BY rand() limit 0,2) as t1
UNION
SELECT * FROM (SELECT * FROM questions WHERE category= 2 ORDER BY rand() limit 0,2) as t2
UNION 
SELECT * FROM (SELECT * FROM questions WHERE category= 3 ORDER BY rand() limit 0,2) as t3
UNION
...

(O Select aninhado permite que você classifique por rand() por categoria)Nada de especial até agora - 2 perguntas aleatórias por categoria.

A parte complicada agora é adicionar o 15º elemento SEM selecionando qualquer um daqueles que você já tem.

Para conseguir isso com "uma" chamada, você pode fazer o seguinte:
  • Faça o subconjunto de 14 perguntas que você selecionou como acima.
  • Unir isso com um conjunto não categorizado de coisas classificadas aleatoriamente do banco de dados. (limite 0,15)

  • Selecione todos deste resultado, limite 0,15.

  • SE os primeiros 14 elementos da subconsulta LAST já estiverem selecionados - eles serão removidos devido a UNION , e um 15º elemento independente é garantido.
  • Se a consulta interna final também selecionar 15 perguntas distintas, o limite externo 0,15 levará apenas a primeira delas para o resultado.

Algo como:
SELECT * FROM (
    SELECT * FROM (SELECT * FROM questions WHERE category= 1 ORDER BY rand() limit 0,2) as t1
    UNION
    SELECT * FROM (SELECT * FROM questions WHERE category= 2 ORDER BY rand() limit 0,2) as t2
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 3 ORDER BY rand() limit 0,2) as t3
    UNION
    ...
    UNION
    SELECT * FROM (SELECT * FROM questions ORDER BY rand() LIMIT 0,15) as t8
) AS tx LIMIT 0,15

Isso é um pouco feio, mas deve fazer exatamente o que você precisa:2 perguntas aleatórias de CADA categoria e, finalmente, uma pergunta aleatória que NÃO foi selecionada já de QUALQUER categoria. Um total de 15 perguntas a qualquer momento.

(Sidenode:Você também pode executar uma segunda consulta, usando NOT IN () para não permitir perguntas já selecionadas após determinar as 14 perguntas para as 7 categorias.)

Edit:Infelizmente o SQL Fiddle não está funcionando no momento. Aqui está algum código de violino:
CREATE TABLE questions (id int(10), category int(10), question varchar(20));

INSERT INTO questions (id, category, question)VALUES(1,1,"Q1");
INSERT INTO questions (id, category, question)VALUES(2,1,"Q2");
INSERT INTO questions (id, category, question)VALUES(3,1,"Q3");
INSERT INTO questions (id, category, question)VALUES(4,2,"Q4");
INSERT INTO questions (id, category, question)VALUES(5,2,"Q5");
INSERT INTO questions (id, category, question)VALUES(6,2,"Q6");
INSERT INTO questions (id, category, question)VALUES(7,3,"Q7");
INSERT INTO questions (id, category, question)VALUES(8,3,"Q8");
INSERT INTO questions (id, category, question)VALUES(9,3,"Q9");
INSERT INTO questions (id, category, question)VALUES(10,4,"Q10");
INSERT INTO questions (id, category, question)VALUES(11,4,"Q11");
INSERT INTO questions (id, category, question)VALUES(12,4,"Q12");
INSERT INTO questions (id, category, question)VALUES(13,5,"Q13");
INSERT INTO questions (id, category, question)VALUES(14,5,"Q14");
INSERT INTO questions (id, category, question)VALUES(15,5,"Q15");
INSERT INTO questions (id, category, question)VALUES(16,6,"Q16");
INSERT INTO questions (id, category, question)VALUES(17,6,"Q17");
INSERT INTO questions (id, category, question)VALUES(18,6,"Q18");
INSERT INTO questions (id, category, question)VALUES(19,7,"Q19");
INSERT INTO questions (id, category, question)VALUES(20,7,"Q20");
INSERT INTO questions (id, category, question)VALUES(21,7,"Q21");

Consulta
SELECT * FROM (
    SELECT * FROM (SELECT * FROM questions WHERE category= 1 ORDER BY rand() limit 0,2) as t1
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 2 ORDER BY rand() limit 0,2) as t2
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 3 ORDER BY rand() limit 0,2) as t3
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 4 ORDER BY rand() limit 0,2) as t4
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 5 ORDER BY rand() limit 0,2) as t5
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 6 ORDER BY rand() limit 0,2) as t6
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 7 ORDER BY rand() limit 0,2) as t7
    UNION 
    SELECT * FROM (SELECT * FROM questions ORDER BY rand() LIMIT 0,15) as t8
) AS tx LIMIT 0,15

os dados de exemplo contêm 3 perguntas por tipo, levando ao resultado que a 15ª pergunta (última linha) é SEMPRE a que resta de uma categoria.