DB2表查询:如何筛选无指定月份付款记录的行
筛选DB2中无指定月份付款记录的账户
这个需求在日常数据查询里挺常见的,我给你分享几种DB2里可行的实现方式,你可以根据自己的场景选最合适的:
方法一:NOT EXISTS子查询(推荐,性能较好)
这种方式逻辑直观,通过子查询检查当前账户是否存在指定月份的付款记录,不存在就保留:
SELECT DISTINCT accountno FROM payment p_main WHERE NOT EXISTS ( SELECT 1 FROM payment p_sub WHERE p_sub.accountno = p_main.accountno -- 这里替换成你要筛选的年份和月份 AND YEAR(p_sub.pay_date) = 2024 AND MONTH(p_sub.pay_date) = 5 )
说明:
DISTINCT是为了去重,因为同一账户可能有多条非指定月份的付款记录,我们只需要每个账户出现一次- 如果你的DB2版本支持
DATE_TRUNC函数,也可以用更简洁的日期判断:DATE_TRUNC('month', p_sub.pay_date) = DATE('2024-05-01'),效果和年份+月份判断一致
方法二:LEFT JOIN + IS NULL
通过左连接指定月份的付款记录,筛选出连接后无匹配的账户:
SELECT DISTINCT p_main.accountno FROM payment p_main LEFT JOIN payment p_sub ON p_main.accountno = p_sub.accountno AND YEAR(p_sub.pay_date) = 2024 AND MONTH(p_sub.pay_date) = 5 WHERE p_sub.accountno IS NULL
说明:
- 左连接会保留主表(
p_main)的所有账户,当某个账户在指定月份没有付款记录时,p_sub的字段会是NULL,我们通过这个条件筛选目标账户
方法三:EXCEPT集合运算
用“所有账户”减去“有指定月份付款的账户”,得到目标结果:
SELECT DISTINCT accountno FROM payment EXCEPT SELECT DISTINCT accountno FROM payment WHERE YEAR(pay_date) = 2024 AND MONTH(pay_date) = 5
说明:
EXCEPT会返回第一个查询中存在,但第二个查询中不存在的记录,正好符合我们“排除有指定月份付款的账户”的需求
额外注意:
如果你的系统里有单独的账户主表(比如叫account),而不仅仅是付款记录表,那更推荐从账户主表出发查询,这样能包含那些从来没有任何付款记录的账户:
SELECT a.accountno FROM account a WHERE NOT EXISTS ( SELECT 1 FROM payment p WHERE p.accountno = a.accountno AND YEAR(p.pay_date) = 2024 AND MONTH(p.pay_date) = 5 )
内容的提问来源于stack exchange,提问作者ams16
相关产品推荐
相关产品推荐

