对于 MySQL,此查询将返回您指定的结果集:
SELECT b.title
, MAX(b.timestamp)
, b.category_id
FROM blogs b
GROUP BY b.category_id
如果在具有相同最新“时间戳”的类别中碰巧有多个“标题”,则只会返回该类别的一行,因此每个类别只会返回一个“标题”。
注意:其他 DBMS 系统将抛出与上述查询类似的异常(错误),因为 SELECT 列表中未出现在 GROUP BY 中的非聚合的处理。
您的查询非常接近。您已经获得了返回每个类别的“最新”时间戳的内部查询。下一步是返回 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 子句。