SQL唯一行查询问题:如何筛选非空值排除空白行
问题分析与解决方案
咱们先拆解下你的原查询为啥达不到预期效果,再给出对应的修正方案:
原查询的核心问题
你的查询用了隐式内连接(Table_1 a, Table_2 b)加上DISTINCT,但**DISTINCT仅对(SR_NUM, Value)的组合去重,并没有针对每个SR_NUM筛选出非空白的Value**。
结合你的数据来看:
- 对应
SR_NUM=1-12345的Row_Id=100,Table_2里有1条Value='Test'和2条空白值。DISTINCT会把('1-12345', 'Test')和('1-12345', '')这两个不同的组合都保留,所以最终返回两条记录,不符合你“仅保留非空白行”的需求。
另外还有个小细节:隐式连接(用逗号分隔表)的写法不如显式INNER JOIN清晰,可读性差且容易误写出笛卡尔积,建议后续优先用显式连接语法。
修正方案
这里提供两种常用的解决思路,你可以根据数据库环境选择:
方案1:分组聚合(简单直接)
利用MAX()函数在每个SR_NUM的分组里优先取非空白的值(如果空白是NULL或空字符串,MAX()会自动跳过空白,保留非空的有效内容):
SELECT a.SR_NUM, MAX(b.Value) AS Value FROM Table_1 a INNER JOIN Table_2 b ON a.Row_Id = b.SRA_Id GROUP BY a.SR_NUM
方案2:窗口函数(灵活可控)
如果后续需要更复杂的筛选规则(比如多个非空白值需按特定逻辑排序),可以用窗口函数给每个SR_NUM的记录标记优先级,把非空白记录排在最前面后取第一条:
WITH RankedValues AS ( SELECT a.SR_NUM, b.Value, -- 非空白记录标记为0(优先级高),空白标记为1,排序后非空白在前 ROW_NUMBER() OVER ( PARTITION BY a.SR_NUM ORDER BY CASE WHEN b.Value IS NOT NULL AND b.Value != '' THEN 0 ELSE 1 END ) AS rn FROM Table_1 a INNER JOIN Table_2 b ON a.Row_Id = b.SRA_Id ) SELECT SR_NUM, Value FROM RankedValues WHERE rn = 1
这两种方案都能实现你的需求:SR_NUM=1-12345仅保留Value='Test'的记录;如果需要完全排除对应全是空白的SR_NUM,可以在查询中额外添加过滤条件。
内容的提问来源于stack exchange,提问作者Amit J
相关产品推荐
相关产品推荐

