sql >> Base de Datos >  >> RDS >> Mysql

MYSQL selecciona 2 filas aleatorias de cada categoría

Solo busca 2 por categoría como lo describiste, y uno al azar al final. No es una consulta, sino un conjunto de resultados, que podría ser lo que necesita:

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
...

(La selección anidada le permite ordenar por rand() por categoría) Nada especial hasta ahora:2 preguntas aleatorias por categoría.

La parte complicada ahora es agregar el elemento 15 SIN seleccionando cualquiera de los que ya tienes.

Para lograr esto con "una" llamada, puede hacer lo siguiente:

  • Tome el subconjunto de 14 preguntas que ha seleccionado como arriba.
  • Une esto con un conjunto no categorizado de elementos ordenados al azar de la base de datos. (límite 0,15)
  • Selecciona todo de este resultado, límite 0,15.

  • SI los primeros 14 elementos de la ÚLTIMA subconsulta ya están seleccionados, se eliminarán debido a UNION , y se garantiza un 15º elemento independiente.

  • Si la consulta interna final también selecciona 15 preguntas distintas, el límite externo de 0,15 solo incluirá la primera de ellas en el 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

Esto es un poco feo, pero debería hacer exactamente lo que necesita:2 preguntas aleatorias de CADA categoría y, finalmente, una pregunta aleatoria que NO ha sido seleccionada de NINGUNA categoría. Un total de 15 preguntas en cualquier momento.

(Nodo lateral:también podría ejecutar una segunda consulta, usando NOT IN () para anular preguntas ya seleccionadas después de determinar las 14 preguntas para las 7 categorías).

Editar:Desafortunadamente, SQL Fiddle no funciona en este momento. Aquí hay un código de violín:

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

los datos del ejemplo contienen 3 preguntas por tipo, lo que lleva al resultado de que la pregunta número 15 (última fila) SIEMPRE es la que queda de una categoría.