尽我所能,我有以下表格结构:
Date | Type | Title
Say Type
是1-10范围内的值,表中有1,000条记录,我想要5条最新的唯一类型记录。所以结果会是这样的:
Date | Type | Title
2009-06-04 14:32:00 | 4 | Zeppo
2009-06-04 14:31:00 | 2 | Groucho
2009-06-04 14:30:00 | 8 | Harpo
2009-06-04 14:29:00 | 5 | Gummo
2009-06-04 14:28:00 | 3 | Chico
似乎我要求DISTINCT
仅适用于Type
列,或者我想要一个GROUP BY
,它将在 {{1}之后应用条款。
全部在MySQL 4中。
答案 0 :(得分:7)
我错过了什么吗?简单的解决方案似乎是:
SELECT MAX(date) AS max_date, type, title
FROM table
GROUP BY
type
ORDER BY
max_date DESC
LIMIT 5
它应该非常快。
答案 1 :(得分:2)
没有为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)
有关其工作原理的详细信息,请参阅我的博客中的此条目:
N
中的GROUP
选择MySQL
行。如果您无法添加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
更有效。
答案 2 :(得分:1)
假设查询性能有点重要并且你遇到了MySQL 4,我会选择这样的东西:
SELECT Date, Type, Title
FROM (
SELECT Date, Type, Title
FROM Table
WHERE Type = 1
ORDER BY Date
LIMIT 1
UNION ALL
SELECT Date, Type, Title
FROM Table
WHERE Type = 2
ORDER BY Date
LIMIT 1
...
) x
ORDER BY Date
LIMIT 5
它不漂亮,但应该快速完成工作。如果您经常向类型列添加新值,则可能不适合您,因为它需要定期修改查询。
我认为派生表是在4.1中添加的,所以你需要在4系列中至少达到那么高。如果您使用的是版本5或其他数据库,那么可以采用更好的方法来解决这个问题。
答案 3 :(得分:1)
这似乎是union语句和嵌套选择的好例子。
有些事情:
select t.date, t.type, t.title from (Select top 5 table.Date, table.Type, table.Title from table where type = 1 order by table.date desc) as t
union
select t2.date, t2.type, t2.title from (Select top 5 table.Date, table.Type, table.Title from table where type = 2 order by table.date desc) as t2
[...]
select t10.date, t10.type, t10.title from (Select top 5 table.Date, table.Type, table.Title from table where type = 10 order by table.date desc) as t10
order by type, date
不幸的是,我只有sql server 2008来测试这个,所以ymmv;但这是非常基本的东西,它应该工作,因为根据参考指南,mysql 4.0支持嵌套选择和联合。 (我已经根据mysql文档将as子句添加到嵌套的from语句中。)
答案 4 :(得分:0)
试试这个
select
T.*
from
(select
max(date) dt,
Type
from
table
group by type
order by dt desc
limit 5) subQuery
inner join table T on T.date = subQuery.dt and T.Type = subQuery.Type
我只在MySQL 5上尝试过。这假设日期字段是唯一的。如果您拥有日期以外的主键,请在查询中使用该键。
答案 5 :(得分:0)
我知道它有点晚了,但遇到了同样的问题,并弄明白了:所以我发布了。
SELECT t.Date, t.Type, t.Title
FROM (SELECT Date, Type, Title FROM table ORDER BY Date DESC) AS t
GROUP BY t.Type LIMIT 5;
我认为这不是一个更简单的解决方案。
<强> 解释 强>
首先执行内部SELECT。这将返回一个表 行,DESC按日期列排序。在此表中,最新条目为 特定类型是相同类型的所有其他条目。 此返回表重命名为t。
现在,基于Type列对此表执行GROUP BY操作。 结果将是每种类型遇到的第一行。
现在添加一个LIMIT条件 得到前5行。