SQL Server中按指定优先级获取TargetValue的查询问题求助
解决按优先级匹配Metric目标值的问题
我来帮你搞定这个按优先级匹配TargetValue的需求!你的核心问题是要给#Metrics中的每条记录,从#MetricTargets里找到唯一符合最高优先级的TargetValue,而不是返回所有匹配的行。
问题分析
你之前的查询用了LEFT JOIN和一些条件尝试匹配不同优先级,但没有做筛选,所以会返回所有满足条件的记录,而不是只保留最高优先级的那一条。我们需要给每个匹配的记录按优先级排序,然后只取排名第一的结果。
解决方案思路
根据你指定的优先级规则,我们可以用ROW_NUMBER()窗口函数,给每个匹配的行分配一个优先级排名:
- 优先级1:
M.AccountId = S.AccountId AND M.CountryId = S.CountryId(完全匹配) - 优先级2:
M.AccountId = S.AccountId AND M.CountryId = -1(账户匹配,国家通配) - 优先级3:
M.AccountId = -1 AND M.CountryId = S.CountryId(账户通配,国家匹配) - 优先级4:
M.AccountId = -1 AND M.CountryId = -1(全通配)
我们用CASE语句把这些优先级转换成数字(数字越小优先级越高),然后按S.MetricId, S.AccountId, S.CountryId分组,对每组内的行按优先级排序,最后只保留排名为1的行。
修正后的查询代码
WITH RankedTargets AS ( SELECT S.MetricId, S.AccountId, S.CountryId, M.TargetValue, -- 按优先级分配排名,数字越小优先级越高 ROW_NUMBER() OVER ( PARTITION BY S.MetricId, S.AccountId, S.CountryId ORDER BY CASE WHEN M.AccountId = S.AccountId AND M.CountryId = S.CountryId THEN 1 WHEN M.AccountId = S.AccountId AND M.CountryId = -1 THEN 2 WHEN M.AccountId = -1 AND M.CountryId = S.CountryId THEN 3 WHEN M.AccountId = -1 AND M.CountryId = -1 THEN 4 ELSE 5 -- 不符合任何规则的行,优先级最低 END ) AS PriorityRank FROM #Metrics S LEFT JOIN #MetricTargets M ON M.MetricId = S.MetricId -- 首先确保MetricId匹配 -- 匹配规则:要么ID相等,要么目标表的ID是-1(通配) AND (M.AccountId = S.AccountId OR M.AccountId = -1) AND (M.CountryId = S.CountryId OR M.CountryId = -1) ) SELECT MetricId, AccountId, CountryId, TargetValue FROM RankedTargets WHERE PriorityRank = 1; -- 只保留最高优先级的记录
代码解释
- CTE
RankedTargets:先连接两个表,匹配规则是MetricId相等,且AccountId/CountryId要么完全匹配,要么目标表的ID是-1(通配)。然后用ROW_NUMBER()给每个分组(每个Metrics记录)的匹配行按优先级排序。 - 主查询:筛选出
PriorityRank=1的行,也就是每个Metrics记录对应的最高优先级TargetValue。
针对你提供的测试数据说明
注意你插入#MetricTargets的语句可能存在列顺序错误(比如#MetricTargets的列顺序是AccountId, MetricId, TargetValue, Countryid,但你插入时的SELECT顺序是AccountId, TargetValue, MetricId, Countryid),导致MetricId和TargetValue的位置颠倒了。如果修正插入语句的列顺序,比如:
INSERT INTO #MetricTargets(AccountId, MetricId, TargetValue, Countryid) SELECT 3, 8253, 100, 105; -- 完全匹配的记录
那修正后的查询就会返回这条记录的TargetValue=100,符合最高优先级的规则。
内容的提问来源于stack exchange,提问作者Veeramalla Sandeep
相关产品推荐
相关产品推荐

