I am trying to get an output of rows that are limited to n per group in MySQL. I can get it to work without joins, but with it I am just shy. I've pasted a dump of the relevant tables here:
The query I am using is:
SELECT title, catRef, RowNum, pCat, tog FROM ( SELECT title, catRef, @num := IF(@prevCat=catRef,@num+1,1) AS RowNum, @prevCat AS tog, @prevCat := catRef AS pCat FROM (select @prevCat:=null) AS initvars CROSS JOIN ( SELECT p.title, oi.catRef FROM resources p INNER JOIN placesRel v ON (p.resId = v.refId) INNER JOIN catRel oi ON (p.resId = oi.refId) WHERE p.status = 'live' AND v.type = 'res' AND oi.type = 'res' ) AS T ) AS U WHERE RowNum <= 5 ORDER BY catRef
I just can't get the row count to go up. Or any other solution would be greatly appreciated.
I'm looking for a result like this:
title catRef RowNum Title1 1 1 Title2 1 2 Title3 1 3 Title4 2 1 Title5 2 2 Title6 3 1
At the moment, the RowNum column is always 1.
SET @num := 1, @prevCat := 0; SELECT title, start, end, type, description, linkOut, outType, catRef, row_number FROM ( SELECT title, start, end, type, description, linkOut, outType, catRef, @num := if(@prevCat = catRef, @num + 1, 1) as row_number, @prevCat AS tog, @prevCat := catRef AS dummy FROM ( SELECT title, start, end, resources.type, description, linkOut, outType, catRef FROM resources LEFT JOIN placesRel ON placesRel.refId = resId LEFT JOIN catRel ON catRel.refId = resId WHERE status = 'live' AND placesRel.type = 'res' AND catRel.type = 'res' ORDER BY catRef ) AS w ) AS x WHERE x.row_number <= 4;
You need to put your joined query in a sub-query and order it by the column you want to group by. Use it's parent query to add row numbers. Then, the top-level query glues it all together.
If you don't put your joined query in it's own sub-query, the results won't be ordered as you wish, but instead will come out in the order they are in the database. This means the data is not grouped, so row numbers will no be applied to ordered rows.