Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MYSQL wybierz 2 losowe wiersze z każdej kategorii

Po prostu pobierz 2 z każdej kategorii, jak opisałeś, i jedną losową na końcu. Nie jest to jedno zapytanie, ale jeden zestaw wyników, który może być tym, czego potrzebujesz:

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

(Zagnieżdżona funkcja Select umożliwia sortowanie według rand() według kategorii) Jak dotąd nic specjalnego - 2 losowe pytania na kategorię.

Trudną częścią jest teraz dodanie 15. elementu BEZ wybierając dowolne z tych, które już masz.

Aby to osiągnąć za pomocą „jednego” połączenia, możesz wykonać następujące czynności:

  • Weź podzbiór 14 pytań, które wybrałeś jak powyżej.
  • Połącz to z nieskategoryzowanym zestawem losowo posortowanych rzeczy z bazy danych. (limit 0,15)
  • Wybierz wszystko z tego wyniku, limit 0,15.

  • JEŚLI pierwszych 14 elementów LAST podzapytania jest już wybranych - zostaną one usunięte z powodu UNION i gwarantowany jest niezależny piętnasty element.

  • Jeśli ostatnie wewnętrzne zapytanie wybierze również 15 odrębnych pytań, zewnętrzny limit 0,15 uwzględni w wyniku tylko pierwsze z nich.

Coś takiego:

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

To trochę brzydkie, ale powinno zrobić dokładnie to, czego potrzebujesz:2 losowe pytania z KAŻDEJ kategorii i wreszcie losowe pytanie, które NIE zostało jeszcze wybrane z ŻADNEJ kategorii. Łącznie 15 pytań w dowolnym momencie.

(Sidenode:Równie dobrze możesz uruchomić drugie zapytanie, używając NOT IN () aby odrzucić już wybrane pytania po określeniu 14 pytań dla 7 kategorii).

Edycja:Niestety SQL Fiddle w tej chwili nie działa. Oto kod skrzypiec:

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

Zapytanie

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

przykładowe dane zawierają 3 pytania każdego typu, co prowadzi do tego, że 15. pytanie (ostatni rząd) jest ZAWSZE tym, które pozostało z kategorii.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mysql porównuje pole oddzielone przecinkami z pojedynczym ciągiem

  2. MySQL CREATE USER ze zmienną?

  3. Jak sprawić, by to zapytanie SQL wyprowadzało dwa wiersze, a nie dwa pola?

  4. Kod błędu:1822, gdy typy danych są zgodne, z kluczem złożonym

  5. SQL dzielony wiersz oddzielony przecinkami