如何按parent_id1和parent_id2分组获取最新文档及对应最新状态?
解决方案
假设表结构
先明确两张表的核心字段(可根据实际情况调整):
Document:document_id,parent_id1,parent_id2,timestamp,(其他业务字段)Document_history:history_id,document_id,status,timestamp,(其他业务字段)
方法一:使用窗口函数(推荐,支持PostgreSQL、MySQL 8.0+、SQL Server等)
通过窗口函数精准分组筛选最新记录,逻辑清晰易维护:
WITH latest_documents AS ( SELECT document_id, parent_id1, parent_id2, timestamp AS doc_timestamp, -- 按需添加Document表的其他字段 ROW_NUMBER() OVER (PARTITION BY parent_id1, parent_id2 ORDER BY timestamp DESC) AS row_rank FROM Document ), latest_history_status AS ( SELECT document_id, status, ROW_NUMBER() OVER (PARTITION BY document_id ORDER BY timestamp DESC) AS row_rank FROM Document_history ) SELECT ld.parent_id1, ld.parent_id2, ld.document_id, ld.doc_timestamp, -- 按需添加其他Document字段 lhs.status AS latest_status FROM latest_documents ld LEFT JOIN latest_history_status lhs ON ld.document_id = lhs.document_id AND lhs.row_rank = 1 WHERE ld.row_rank = 1;
逻辑说明:
latest_documents子句:按parent_id1+parent_id2分组,给每组内的记录按timestamp倒序排名,取排名第一的即为该组最新文档。latest_history_status子句:按document_id分组,给每个文档的历史记录按timestamp倒序排名,取排名第一的即为该文档的最新状态。- 最后关联两个子句,得到目标结果。
方法二:关联子查询(兼容老版本数据库,如MySQL 5.x)
如果数据库不支持窗口函数,用关联子查询实现:
SELECT d.document_id, d.parent_id1, d.parent_id2, d.timestamp AS doc_timestamp, -- 按需添加Document表的其他字段 ( SELECT status FROM Document_history dh WHERE dh.document_id = d.document_id ORDER BY dh.timestamp DESC LIMIT 1 ) AS latest_status FROM Document d WHERE d.timestamp = ( SELECT MAX(timestamp) FROM Document WHERE parent_id1 = d.parent_id1 AND parent_id2 = d.parent_id2 );
逻辑说明:
- 外层WHERE条件筛选出每组(
parent_id1+parent_id2)中timestamp最大的文档记录。 - 子查询获取该文档对应的最新历史状态,通过倒序排序+限制1条取最新。
注意事项
- 如果同一分组内存在多条
timestamp完全相同的最新文档,窗口函数中ROW_NUMBER()会随机保留一条,若想保留所有同时间的记录,替换为RANK()即可。 - 若某文档无历史记录,
LEFT JOIN会返回NULL作为latest_status,符合左关联的预期逻辑。
内容的提问来源于stack exchange,提问作者ehsun7b
相关产品推荐
相关产品推荐

