如何从JSON_VALUE查询结果中去除重复零件编号记录
解决方案
你的原SQL里用DISTINCT没法实现去重,因为i.id是唯一字段,每条记录的id都不一样,DISTINCT会把所有记录都保留下来。要实现每个partNumber只留一条记录,推荐用窗口函数ROW_NUMBER()来处理:
方法1:使用CTE(公共表表达式)
WITH RankedParts AS ( SELECT i.Id, JSON_VALUE(i.Details, '$.partNumber') AS PartNumber, JSON_VALUE(i.Details, '$.qty') AS Qty, i.BrandId, -- 按零件编号分组,每组内按Id升序排序,给记录打行号 ROW_NUMBER() OVER (PARTITION BY JSON_VALUE(i.Details, '$.partNumber') ORDER BY i.Id ASC) AS RowNum FROM PartDetailsTable i ) SELECT rp.Id, rp.PartNumber, rp.Qty, rp.BrandId, b.BrandName FROM RankedParts rp INNER JOIN Brands b ON rp.BrandId = b.Id WHERE rp.RowNum = 1; -- 只保留每组的第一条记录
方法2:使用子查询
如果你的SQL环境不支持CTE,也可以用子查询实现相同效果:
SELECT sub.Id, sub.PartNumber, sub.Qty, sub.BrandId, b.BrandName FROM ( SELECT i.Id, JSON_VALUE(i.Details, '$.partNumber') AS PartNumber, JSON_VALUE(i.Details, '$.qty') AS Qty, i.BrandId, ROW_NUMBER() OVER (PARTITION BY JSON_VALUE(i.Details, '$.partNumber') ORDER BY i.Id ASC) AS RowNum FROM PartDetailsTable i ) sub INNER JOIN Brands b ON sub.BrandId = b.Id WHERE sub.RowNum = 1;
说明
- 这里的逻辑是给每个相同
partNumber的记录分组,按Id从小到大排序,取每组的第一条(也就是RowNum=1),对应你示例里要保留的Id1、3、4、5。 - 如果需要按其他规则保留记录(比如保留数量最多、价格最高的那条),只需要修改
ORDER BY后的字段即可,比如改成ORDER BY i.Qty DESC或ORDER BY i.Price DESC。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

