SQL实现:按指定优先级为每个编号从多行记录中返回唯一名称
实现按优先级获取多语言名称的SQL方案
Hey,我明白你折腾了好几个小时没搞定的痛苦,这种按优先级取值的需求在多语言数据处理里挺常见的,给你两种靠谱的SQL实现方案,都能满足你的要求:
方案一:使用窗口函数(ROW_NUMBER())
这种方法的核心是给每个Number下的记录按语言优先级排序,然后取排序第一的那条记录的名称,没有符合条件的就返回默认值。
WITH ranked_names AS ( SELECT Number, Name, ROW_NUMBER() OVER ( PARTITION BY Number ORDER BY CASE Language WHEN 'E' THEN 1 WHEN 'D' THEN 2 ELSE 3 END ) AS rn FROM your_table_name ) SELECT Number, COALESCE(MAX(CASE WHEN rn = 1 THEN Name END), 'name not available') AS Name FROM ranked_names GROUP BY Number;
逻辑解释:
- 用CTE(
ranked_names)给每个Number分组,按照E > D > 其他语言的优先级排序,英文记录会被标记为rn=1,德文为rn=2,其他语言为rn=3。 - 最后分组筛选每个
Number中rn=1的名称,如果没有符合条件的记录(比如示例中的3333),COALESCE会自动返回我们指定的默认字符串。
方案二:使用条件聚合+COALESCE
这种写法更简洁,直接通过条件判断聚合出对应优先级的名称,不需要窗口函数:
SELECT Number, COALESCE( MAX(CASE WHEN Language = 'E' THEN Name END), MAX(CASE WHEN Language = 'D' THEN Name END), 'name not available' ) AS Name FROM your_table_name GROUP BY Number;
逻辑解释:
MAX(CASE WHEN Language = 'E' THEN Name END)会提取每个Number下的英文名称,如果不存在就返回NULL。COALESCE会依次检查传入的参数,返回第一个非NULL的值:如果有英文就返回英文,没有就返回德文,两者都没有就返回默认字符串。
两种方案都能完美输出你期望的结果,适配绝大多数主流数据库(MySQL、PostgreSQL、SQL Server等),可以根据自己的习惯和数据量选择使用~
内容的提问来源于stack exchange,提问作者Kati XX
相关产品推荐
相关产品推荐

