如何实现INNER JOIN后仅首行保留Val_2值,其余显示NULL?
解决关联后字段重复显示的问题
嗨,这个需求很常见,咱们可以利用窗口函数来实现只在分组首行保留val_2值、其余行显示NULL的效果,下面是具体方案:
通用解决方案(支持MySQL 8.0+、PostgreSQL、SQL Server等)
使用ROW_NUMBER()窗口函数给每个row_id分组内的行标记序号,通过CASE语句判断是否为分组首行来控制val_2的显示:
SELECT a.row_id, a.category, a.val_1, CASE WHEN ROW_NUMBER() OVER (PARTITION BY a.row_id ORDER BY a.category) = 1 THEN b.val_2 ELSE NULL END AS val_2 FROM TABLE_A a INNER JOIN TABLE_B b ON a.row_id = b.row_id;
代码说明:
PARTITION BY a.row_id:按row_id对数据分组,确保每个row_id下的行独立处理ORDER BY a.category:指定分组内的行排序规则,确保你想要的首行(比如示例中的cat1)排在第一位,你也可以根据实际需求换成val_1或其他字段CASE逻辑:仅当行是分组内的第一行时,返回val_2的值,其余行返回NULL
兼容老版本MySQL(5.x及以下)的方案
如果你的数据库不支持窗口函数,可以用用户变量来实现相同效果:
SELECT row_id, category, val_1, val_2 FROM ( SELECT a.row_id, a.category, a.val_1, CASE WHEN @prev_row != a.row_id THEN @val := b.val_2 ELSE @val := NULL END AS val_2, @prev_row := a.row_id FROM TABLE_A a INNER JOIN TABLE_B b ON a.row_id = b.row_id CROSS JOIN (SELECT @prev_row := NULL, @val := NULL) init_vars ORDER BY a.row_id, a.category ) AS temp;
这个写法通过变量记录上一行的row_id,当row_id变化时赋值val_2,否则置为NULL,外层查询用来隐藏中间变量,让结果更干净。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

