Cette requête renvoie tous les éléments joints aux catégories dans un ordre aléatoire :
SELECT
c.id AS cid, c.category, i.id AS iid, i.name
FROM categories c
INNER JOIN items i ON c.id = i.category
ORDER BY RAND()
Pour limiter chaque catégorie à une, enveloppez la requête dans un partiel GROUP BY
:
SELECT * FROM (
SELECT
c.id AS cid, c.category, i.id AS iid, i.name
FROM categories c
INNER JOIN items i ON c.id = i.category
ORDER BY RAND()
) AS shuffled_items
GROUP BY cid
Notez que lorsqu'une requête a à la fois GROUP BY
et ORDER BY
clause, le regroupement est effectué avant le tri. C'est pourquoi j'ai utilisé deux requêtes :la première trie les résultats, la seconde regroupe les résultats.
Je comprends que cette requête ne va pas gagner de course. Je suis ouvert aux suggestions.