Didn't test in for MySQL 4
, but in MySQL 5
this can be easily done.
You'll need to have some kind of a PRIMARY KEY
in your table for this to work.
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 entry in my blog for more detail on how it works:
If you cannot add a PRIMARY KEY
to implement this solution, you may try using 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's described here:
Update:
If you don't want to select 5
records for each type (which would give 5 x number of types
records in the resultset), but instead want to select 5
latest records with distinct type (which would give 5
records in the resultset), 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 lots of types, this will be more efficient that using GROUP BY
, provided you have an index on date
.