Esta consulta devuelve todos los elementos unidos a categorías en orden aleatorio:
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()
Para restringir cada categoría a una, ajuste la consulta en un parcial 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
Tenga en cuenta que cuando una consulta tiene tanto GROUP BY
y ORDER BY
cláusula, la agrupación se realiza antes de la clasificación. Es por eso que he usado dos consultas:la primera ordena los resultados, la segunda agrupa los resultados.
Entiendo que esta consulta no va a ganar ninguna carrera. Estoy abierto a sugerencias.