Sybase ASE 16.0:筛选满足子集求和条件的指定记录
在Sybase ASE 16.0中筛选和为指定值的记录子集
需求说明
需要从RECORDS表中筛选满足以下条件的记录:
SECURITIES_ID = 'B'DEBITCREDIT = 'D'- 选中的记录子集的
NOMINAL_VALUE之和等于300
示例中可选RECORD_ID为2和4(二者和为300),若存在多个符合条件的组合,任选其一即可。原查询因计算所有符合条件记录的总和(301),无法得到目标结果。
测试数据
create table RECORDS (RECORD_ID int ,SECURITIES_ID char(1) ,DEBITCREDIT char(1) ,NOMINAL_VALUE int ,BOOKING_ID int ) go insert RECORDS values (1,'A','C',100,10) insert RECORDS values (2,'B','D',100,20) insert RECORDS values (3,'B','C',100,30) insert RECORDS values (4,'B','D',200,40) insert RECORDS values (5,'C','D', 50,50) insert RECORDS values (6,'B','D', 1,60) go
解决方案
使用递归CTE遍历所有符合条件的记录组合,筛选出和为300的子集:
WITH RECURSIVE subset_cte AS ( -- 基础成员:单个符合条件的记录 SELECT RECORD_ID, BOOKING_ID, NOMINAL_VALUE AS total_sum, CAST(RECORD_ID AS VARCHAR(100)) AS record_list FROM RECORDS WHERE SECURITIES_ID = 'B' AND DEBITCREDIT = 'D' UNION ALL -- 递归成员:组合现有子集与后续记录,累加求和 SELECT r.RECORD_ID, r.BOOKING_ID, sc.total_sum + r.NOMINAL_VALUE AS total_sum, sc.record_list + ',' + CAST(r.RECORD_ID AS VARCHAR(100)) AS record_list FROM subset_cte sc JOIN RECORDS r ON r.RECORD_ID > sc.RECORD_ID -- 避免生成重复组合(如2+4和4+2) AND r.SECURITIES_ID = 'B' AND r.DEBITCREDIT = 'D' WHERE sc.total_sum + r.NOMINAL_VALUE <= 300 -- 提前终止超过目标值的组合 ) -- 筛选出总和为300的子集,取其中一组返回对应记录 SELECT RECORD_ID, BOOKING_ID FROM RECORDS WHERE RECORD_ID IN ( SELECT CAST(value AS INT) FROM STRING_SPLIT( (SELECT TOP 1 record_list FROM subset_cte WHERE total_sum = 300), ',' ) ) ORDER BY RECORD_ID;
说明
- 递归CTE先构造单条记录的基础子集,再逐步组合后续记录,累加计算和。
- 通过
RECORD_ID > sc.RECORD_ID避免生成重复的组合,提升效率。 - 用
TOP 1任选一个符合条件的组合,满足需求中“任选其一”的要求。
内容的提问来源于stack exchange,提问作者Thomas_SO
相关产品推荐
相关产品推荐

