SQL Server按InfoID分组时筛选非BBx类CompName并关联对应Comp
解决SQL Server中按组优先筛选特定格式记录的问题
你的问题核心是按InfoID分组后,要优先选择CompName不是BBx格式的行,但用MAX这类聚合函数根本做不到精准匹配——因为MAX是按字符串字典序取最大值,像InfoID=196672里的BBZ比AAA字典序大,自然就被MAX选中了,这完全不符合你的需求。
正确的做法是用窗口函数给每组内的行做优先级排序,然后取优先级最高的那一行,具体实现如下:
WITH RankedPanels AS ( SELECT PlanID, InfoID, Comp, CompName, GuidID, Object, -- 给每个InfoID分组的行设置优先级:非BB开头的排第一 ROW_NUMBER() OVER ( PARTITION BY InfoID ORDER BY CASE WHEN CompName NOT LIKE 'BB%' THEN 0 ELSE 1 END, -- 优先级:非BBx > BBx PlanID ASC -- 若有多个非BBx行,可选按PlanID取最早/最晚的,这里匹配你的期望结果 ) AS RowNum FROM [Prod].[dbo].[Panel] ) SELECT PlanID, InfoID, Comp, CompName, GuidID, Object FROM RankedPanels WHERE RowNum = 1 -- 取每组优先级最高的第一行 ORDER BY InfoID DESC;
代码解释:
- CTE
RankedPanels:给每行添加一个RowNum序号,按InfoID分组,排序规则是:- 先判断
CompName是否以BB开头,不是的话赋值0(优先级更高),是的话赋值1(优先级更低) - 如果同一组里有多个非BBx的行,再通过
PlanID ASC选择PlanID最小的那一行(你可以改成DESC取最大的,按需调整)
- 先判断
- 主查询:筛选出每组
RowNum=1的行,就是你要的优先非BBx的记录,且所有字段都是对应行的原始值,不会像MAX那样出现字段不匹配的问题。
用这个语句跑出来的结果完全符合你的期望:
- InfoID=196672选到AAA的行
- InfoID=196673选到CCC的行
- InfoID=196674选到DDS的行
内容的提问来源于stack exchange,提问作者gmt
相关产品推荐
相关产品推荐

