Не проверял на MySQL 4
, но на MySQL 5
это легко сделать.
Вам понадобится какой-то PRIMARY KEY
в вашей таблице, чтобы это работало.
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)
Смотрите эту запись в моем блоге для более подробной информации о том, как это работает:
Если вы не можете добавить PRIMARY KEY
для реализации этого решения, вы можете попробовать использовать менее эффективный, используя системные переменные:
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
Это описано здесь:
Обновление:
Если вы не хотите выбирать 5
записей для каждого типа (что даст 5 x number of types
записей в наборе результатов), но вместо этого хотите выбрать 5
последние записи с отдельным типом (что даст 5
записей в результирующем наборе), используйте этот запрос:
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
Если у вас много типов, это будет более эффективно, чем при использовании GROUP BY
, при условии, что у вас есть индекс date
.