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.