我有一个MySQL数据库(博客),它有id,title,timestamp和category_id列名。如何从每个具有最新时间戳的类别中选择一行? 如果我有3行属于类别1,2,1,那么我将返回两行,其中“1”中类别的最高时间戳作为第一行,而行类别“2”作为第二行。
我试过了:
SELECT title, timestamp, category_id
FROM blogs
WHERE timestamp IN (
SELECT MAX(timestamp)
FROM blogs
GROUP BY category_id
)
但由于时间戳不是唯一的,因此可以拉入一个额外的行,其中category_id = 1与内部select语句中选择的category_id = 2的行具有相同的时间戳。
答案 0 :(得分:9)
对于MySQL,此查询将返回您指定的结果集:
SELECT b.title
, MAX(b.timestamp)
, b.category_id
FROM blogs b
GROUP BY b.category_id
如果在具有相同最新“时间戳”的类别中碰巧有多个“标题”,则只返回该类别的一行,因此您将只获得一个“标题“为每个类别返回。
注意:由于处理SELECT列表中未出现在GROUP BY中的非聚合,其他DBMS系统将使用上述查询引发异常(错误)。
您的查询非常接近。您已经有内部查询返回每个类别的“最新”时间戳。下一步是返回category_id以及最新的时间戳。
SELECT category_id, MAX(timestamp) AS timestamp
FROM blogs
GROUP BY category_id
下一步是将其加入blogs
,以获取相关的“标题”
SELECT b.title
, b.timestamp
, b.category_id
FROM (SELECT category_id, MAX(timestamp) AS timestamp
FROM blogs
GROUP BY category_id
) l
JOIN blogs b
ON b.category_id = l.category_id AND b.timestamp = l.timestamp
注意:如果某个类别有多个“最新”行(时间戳值匹配),则此查询将返回这两个行。
如果这是一个问题,可以修改(或以不同的方式编写)查询,以防止类别的两行可能。
简单地向该查询添加GROUP BY子句将起作用(仅在MySQL中,而不是在其他DBMS中)
SELECT b.title
, b.timestamp
, b.category_id
FROM (SELECT category_id, MAX(timestamp) AS timestamp
FROM blogs
GROUP BY category_id
) l
JOIN blogs b
ON b.category_id = l.category_id AND b.timestamp = l.timestamp
GROUP BY b.timestamp, b.category_id
(对于其他DBMS,您可以修改SELECT列表,将b.title
替换为MAX(b.title) AS title
。当您从行返回单个列时,这将起作用。
如果要按特定顺序返回行,请添加ORDER BY子句。
答案 1 :(得分:0)
您也可以尝试这种方式。当我在MYSQL 5.6中尝试时,对我有用。它返回两个类别,其中包含category_id的最高时间戳和升序。
选择标题 ,时间戳 ,category_id FROM blogs WHERE时间戳记(从按类别列出的博客组中选择最大值(时间戳))group by time_amp,category_id order by category_id asc;