Oracle SQL需求:排除存在非空ACTIVATION_DATE的ID所有记录
解决方案:排除存在非空ACTIVATION_DATE的ID的所有记录
要实现“若某ID存在至少一行ACTIVATION_DATE非空的记录,则该ID的所有行都忽略”的需求,确实需要用到子查询或窗口函数,以下是几种可行的方案:
方法一:使用NOT EXISTS子查询(推荐,性能更优)
通过子查询检查当前ID是否存在非空的ACTIVATION_DATE记录,若不存在则保留:
SELECT t.ID, t.ACTIVATION_DATE, t.ACCEPTED_DATE FROM YOUR_TABLE t WHERE t.ACCEPTED_DATE IS NOT NULL AND t.ID IN ('AA1','AA2') AND NOT EXISTS ( SELECT 1 FROM YOUR_TABLE t2 WHERE t2.ID = t.ID AND t2.ACTIVATION_DATE IS NOT NULL );
方法二:使用NOT IN子查询
先筛选出所有存在非空ACTIVATION_DATE的ID,再在主查询中排除这些ID:
SELECT ID, ACTIVATION_DATE, ACCEPTED_DATE FROM YOUR_TABLE WHERE ACCEPTED_DATE IS NOT NULL AND ID IN ('AA1','AA2') AND ID NOT IN ( SELECT DISTINCT ID FROM YOUR_TABLE WHERE ACTIVATION_DATE IS NOT NULL );
注意:若子查询结果包含NULL,NOT IN会导致整个条件不返回任何结果,因此这种方法适合确认子查询无NULL的场景。
方法三:使用窗口函数(单表扫描,大表更高效)
通过窗口函数MAX(ACTIVATION_DATE)按ID分组判断是否存在非空值,若分组后的最大值为NULL,说明该ID所有行的ACTIVATION_DATE都为空:
SELECT ID, ACTIVATION_DATE, ACCEPTED_DATE FROM ( SELECT ID, ACTIVATION_DATE, ACCEPTED_DATE, MAX(ACTIVATION_DATE) OVER (PARTITION BY ID) AS MAX_ACT_DATE FROM YOUR_TABLE WHERE ACCEPTED_DATE IS NOT NULL AND ID IN ('AA1','AA2') ) sub_query WHERE MAX_ACT_DATE IS NULL;
注意事项
- 替换SQL中的
YOUR_TABLE为实际表名,避免使用Oracle关键字TABLE作为表名。 - 若表数据量较大,优先选择NOT EXISTS或窗口函数方案,前者利用索引的概率更高,后者只需扫描一次表。
内容的提问来源于stack exchange,提问作者J_Spenny
相关产品推荐
相关产品推荐

