MySQL查询问题:如何获取每个nid对应最大vid行的title
解决node_revision表获取每个nid最大vid对应title的问题
我来帮你搞定这个问题!你当前的SQL逻辑存在明显错误,WHERE title = vid这部分完全不符合需求(title是文本内容,vid是数字,两者没有相等的业务逻辑),而且GROUP BY的用法也不对,导致你拿不到对应最大vid的title。下面给你两种靠谱的解决方案:
方法一:子查询关联(兼容大多数数据库)
这种方法先通过子查询拿到每个nid的最大vid,再和原表关联匹配,从而获取对应行的title:
SELECT nr.nid, nr.vid, nr.title FROM node_revision nr INNER JOIN ( -- 先获取每个nid对应的最大vid SELECT nid, MAX(vid) AS max_vid FROM node_revision GROUP BY nid ) max_vids ON nr.nid = max_vids.nid AND nr.vid = max_vids.max_vid;
逻辑说明:
- 子查询
max_vids会返回每个nid及其对应的最大vid值 - 用
INNER JOIN将原表node_revision和子查询结果关联,匹配条件是nid相同且当前行的vid等于该nid的最大vid - 这样就能精准获取每个nid下最大vid对应的那一行的所有字段(包括title)
方法二:窗口函数(适合MySQL 8+、PostgreSQL等支持SQL标准的数据库)
如果你的数据库支持窗口函数,这种写法更简洁直观:
SELECT nid, vid, title FROM ( SELECT nid, vid, title, -- 按nid分组,每组内按vid降序排序,给每行标序号 ROW_NUMBER() OVER (PARTITION BY nid ORDER BY vid DESC) AS rn FROM node_revision ) ranked -- 取每组内序号为1的行(也就是vid最大的那一行) WHERE rn = 1;
逻辑说明:
PARTITION BY nid会把数据按nid分成不同的组ORDER BY vid DESC让每个组内vid最大的行排在最前面ROW_NUMBER()给每组内的行从1开始标序号,序号1的就是我们要的最大vid对应的行- 外层查询筛选出
rn=1的行,就能得到目标数据
修正你原SQL的问题
你原来的SQL:
SELECT nid, MAX(vid) as vid, title FROM node_revision WHERE title = vid GROUP BY nid
存在两个核心问题:
WHERE title = vid完全错误:title是文章标题,vid是版本号,两者没有相等的业务逻辑,这会过滤掉几乎所有正确数据GROUP BY nid后直接选title:大多数严格模式的数据库会报错(非聚合列未包含在GROUP BY中),即使MySQL允许,也只会返回该nid下任意一行的title,而非最大vid对应的title
PHP处理示例
执行正确的SQL后,你可以这样提取title列表:
// 假设你用mysqli连接数据库,$conn是连接对象 $query = "SELECT nr.title FROM node_revision nr INNER JOIN (SELECT nid, MAX(vid) AS max_vid FROM node_revision GROUP BY nid) max_vids ON nr.nid = max_vids.nid AND nr.vid = max_vids.max_vid"; $result = mysqli_query($conn, $query); $titles = []; if ($result) { while ($row = mysqli_fetch_assoc($result)) { $titles[] = $row['title']; } mysqli_free_result($result); } // 现在$titles就是所有符合条件的title列表
内容的提问来源于stack exchange,提问作者Aishah91
相关产品推荐
相关产品推荐

