Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL seleziona 2 righe casuali da ciascuna categoria

Prendi solo 2 per categoria come hai descritto e uno casuale alla fine. Non è una query, ma un set di risultati, che potrebbe essere ciò di cui hai bisogno:

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 selezione nidificata ti consente di ordinare per rand() per categoria) Niente di speciale finora - 2 domande casuali per categoria.

La parte difficile ora è aggiungere il 15° elemento SENZA selezionando uno di quelli che hai già.

Per raggiungere questo obiettivo con "una" chiamata, puoi fare quanto segue:

  • Prendi il sottoinsieme di 14 domande che hai selezionato come sopra.
  • Unisci questo con un insieme non categorizzato di cose ordinate casualmente dal database. (limite 0,15)
  • Seleziona tutto da questo risultato, limite 0,15.

  • SE i primi 14 elementi dell'ULTIMA sottoquery sono già selezionati, verranno rimossi a causa di UNION , ed è garantito un 15° elemento indipendente.

  • Se la query interna finale seleziona anche 15 domande distinte, il limite esterno 0,15 porterà solo la prima di esse nel risultato.

Qualcosa come:

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

Questo è alquanto brutto, ma dovrebbe fare esattamente ciò di cui hai bisogno:2 domande casuali da OGNI categoria e infine una domanda casuale che NON è già stata selezionata da NESSUNA categoria. Un totale di 15 domande in qualsiasi momento.

(Sidenode:potresti anche eseguire una seconda query, usando NOT IN () di non consentire domande già selezionate dopo aver determinato le 14 domande per le 7 categorie.)

Modifica:sfortunatamente SQL Fiddle non funziona al momento. Ecco un po' di codice 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");

Interroga

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

i dati di esempio contengono 3 domande per tipo, portando al risultato che la quindicesima domanda (ultima riga) è SEMPRE quella rimanente di una categoria.