Select all categories and news in the correct order, wrap the result in a subquery, add a counter to it and number the news separately for each category, and then just leave the ones you need.
Example for LIMIT 2 (change at your discretion to 5 or whatever):
SELECT t.*, @newsNum := IF(t.id != @prevCatId, 1, @newsNum + 1) n, @prevCatId := t.id FROM ( SELECT c.id, c.category, n.title FROM _category c INNER JOIN _news n ON n.category_id = c.id ORDER BY c.id, n.id ) t INNER JOIN (SELECT @prevCatId := 0, @newsNum := 0) counters HAVING n < 3;
Result (hidden fields):
1 sport news 1.1 1 sport news 1.2 2 cinema news 2.1 2 cinema news 2.2 3 music news 3.1 3 music news 3.2
For debugging I used such temporary tables:
CREATE TEMPORARY TABLE _category(id int, category char(8)) SELECT 1 id, 'sport' category UNION SELECT 2 id, 'cinema' category UNION SELECT 3 id, 'music' category ; CREATE TEMPORARY TABLE _news(id int, category_id int, title char(16)) SELECT 1 id, 1 category_id, 'news 1.1' title UNION SELECT 2 id, 1 category_id, 'news 1.2' title UNION SELECT 3 id, 1 category_id, 'news 1.3' title UNION SELECT 4 id, 2 category_id, 'news 2.1' title UNION SELECT 5 id, 2 category_id, 'news 2.2' title UNION SELECT 6 id, 2 category_id, 'news 2.3' title UNION SELECT 7 id, 3 category_id, 'news 3.1' title UNION SELECT 8 id, 3 category_id, 'news 3.2' title UNION SELECT 9 id, 3 category_id, 'news 3.3' title ;