SQL查询需求:按ID过滤含NULL/空值行,保留指定记录
解决方案
核心思路是先为每个objid计算两个关键指标:是否存在过old_param/new_param为NULL或空串的记录,以及该类记录的最后出现日期,再基于这两个指标统一筛选行。
完整SQL查询
WITH objid_null_info AS ( SELECT objid, -- 计算当前objid最后一次出现NULL/空串的日期 MAX(CASE WHEN ISNULL(old_param, '') = '' OR ISNULL(new_param, '') = '' THEN [date] END) AS last_null_date, -- 标记当前objid是否存在过NULL/空串记录 CASE WHEN EXISTS ( SELECT 1 FROM {table name} t2 WHERE t2.objid = t1.objid AND (ISNULL(t2.old_param, '') = '' OR ISNULL(t2.new_param, '') = '') ) THEN 1 ELSE 0 END AS has_null FROM {table name} t1 GROUP BY objid ) SELECT {various columns} -- 替换为你需要的具体列 FROM {table name + joins} t JOIN objid_null_info n ON t.objid = n.objid WHERE -- 需求1:无NULL/空串的objid,保留所有行 n.has_null = 0 -- 需求2:有NULL/空串的objid,仅保留日期>=最后一次NULL记录的行 OR t.[date] >= n.last_null_date;
关键细节说明
- NULL与空串统一判断:用
ISNULL(col, '') = ''把NULL和空串视为同一类,适配你的需求。如果是MySQL环境,可替换为IFNULL(col, '') = ''。 - CTE的作用:
objid_null_info按objid分组,一次性计算出每个objid的状态标记和关键日期,避免重复子查询。 - 筛选逻辑:通过
has_null区分两种需求场景,用OR连接两个条件,一次查询完成所有筛选,比UNION更高效简洁。
内容的提问来源于stack exchange,提问作者crsmn
相关产品推荐
相关产品推荐

