Not tested for MySQL 4 , but in MySQL 5 it can be done easily.
For this you need some kind of PRIMARY KEY in your table.
SELECT l.* FROM ( SELECT type, COALESCE( ( SELECT id FROM mytable li WHERE li.type= dlo.type ORDER BY li.type DESC, li.date DESC, li.id DESC LIMIT 4, 1 ), CAST(0xFFFFFFFF AS DECIMAL)) AS mid COALESCE( ( SELECT date FROM mytable li WHERE li.type= dlo.type ORDER BY li.type DESC, li.date DESC, li.id DESC LIMIT 4, 1 ), '9999-31-12') AS mdate FROM ( SELECT DISTINCT type FROM t_mytable dl ) dlo ) lo, t_mytable l WHERE l.type >= lo.type AND l.type <= lo.type AND (l.date, l.id) >= (lo.mdate, lo.mid)
See this blog post for more details on how this works:
If you cannot add a PRIMARY KEY to implement this solution, try using a less efficient one using system variables:
SELECT l.* FROM ( SELECT @lim := 5, @cg := -1 ) vars, mytable l WHERE CASE WHEN @cg <> type THEN @r := @lim ELSE 1 END > 0 AND (@r := @r - 1) >= 0 AND (@cg := type) IS NOT NULL ORDER BY type DESC, date DESC
It is described here:
Update:
If you do not want to select 5 records for each type (which will give 5 x number of types records in the result set), but instead want to select the last 5 records with a separate type (which will give 5 records in the result set), use this query:
SELECT date, type, title FROM mytable m WHERE NOT EXISTS ( SELECT 1 FROM mytable mi WHERE mi.date > m.date AND mi.type = m.type ) ORDER BY date DESC LIMIT 5
If you have many types, it will be more efficient if you use GROUP BY , if you have an index on date .