Mysql
 sql >> Base de données >  >> RDS >> Mysql

MYSQL sélectionne 2 lignes aléatoires dans chaque catégorie

Récupérez-en simplement 2 par catégorie comme vous l'avez décrit, et un au hasard à la fin. Il ne s'agit pas d'une requête, mais d'un ensemble de résultats, ce dont vous avez peut-être besoin :

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 sélection imbriquée vous permet de trier par rand() par catégorie) Rien de spécial jusqu'à présent - 2 questions aléatoires par catégorie.

La partie délicate consiste maintenant à ajouter le 15e élément SANS en sélectionnant l'un de ceux que vous avez déjà.

Pour y parvenir avec "un" appel, vous pouvez procéder comme suit :

  • Prenez le sous-ensemble de 14 questions que vous avez sélectionnées comme ci-dessus.
  • Réunissez ceci avec un ensemble non catégorisé d'éléments triés au hasard à partir de la base de données. (limite 0,15)
  • Tout sélectionner dans ce résultat, limite 0,15.

  • SI les 14 premiers éléments de la sous-requête LAST sont déjà sélectionnés - ils seront supprimés en raison de UNION , et un 15ème élément indépendant est garanti.

  • Si la requête interne finale sélectionne également 15 questions distinctes, la limite externe de 0,15 ne prendra que la première d'entre elles dans le résultat.

Quelque chose comme :

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

C'est un peu moche, mais devrait faire exactement ce dont vous avez besoin :2 questions aléatoires de CHAQUE catégorie, et enfin une question aléatoire qui n'a PAS déjà été sélectionnée dans AUCUNE catégorie. Un total de 15 questions à tout moment.

(Sidenode :vous pouvez également exécuter une deuxième requête, en utilisant NOT IN () pour interdire les questions déjà sélectionnées après avoir déterminé les 14 questions pour les 7 catégories.)

Edit :Malheureusement, SQL Fiddle ne fonctionne pas pour le moment. Voici un code de violon :

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

Requête

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

les données d'exemple contiennent 3 questions par type, ce qui fait que la 15e question (dernière ligne) est TOUJOURS celle qui reste d'une catégorie.