MS-SQL查询父表关联子表最新满足条件记录的方法
MS SQL Server 2017 实现方案
你之前用INNER JOIN加GROUP BY写法拿不到正确结果,核心原因是分组聚合后只能拿到聚合计算值,无法直接关联到最新时间戳对应的完整子表行记录,用SQL Server支持的窗口函数ROW_NUMBER()可以非常简洁地解决这个问题,逻辑步骤如下:
- 先对子表B做窗口计算:按关联字段
Main分区,每个分区内按Timestamp倒序排序,给每条记录生成行号,每个Main下时间戳最新的记录行号固定为1 - 关联表A和处理后的子表B,关联条件除了Main字段匹配,仅保留子表行号为1的记录(即每个Main对应的最新子表记录)
- 最后加两层过滤:表A的
Status值为1,且关联到的最新子表记录的C-Status值为'c'
完整可直接运行的SQL如下:
SELECT A.Main, B.[C-Status], B.Timestamp, A.Reference FROM A INNER JOIN ( SELECT Main, [C-Status], Timestamp, ROW_NUMBER() OVER (PARTITION BY Main ORDER BY Timestamp DESC, ID DESC) AS row_rank FROM B ) B ON A.Main = B.Main AND B.row_rank = 1 WHERE A.Status = 1 AND B.[C-Status] = 'c';
补充说明
- 针对你给出的样例数据,上述SQL执行后仅会返回
Main=2的记录,对应字段值为C-Status='c'、Timestamp=6、Reference='AB',完全匹配你的筛选规则。 - 窗口函数的
ORDER BY里加了ID DESC作为兜底排序规则,避免同一个Main下出现多条Timestamp相同的最大值记录时,返回结果不稳定。如果业务上允许同时间戳的最新记录全部返回,可以把ROW_NUMBER()替换为RANK()。 - 注意字段
C-Status带中划线,在SQL Server中必须用方括号[]包裹,否则会被解析为减法运算抛出语法错误。
内容的提问来源于stack exchange,提问作者Steven Tschache
相关产品推荐
相关产品推荐

