获取各账户最后一笔特定费用日期时SQL报错问题排查
问题分析与解决方案
报错原因
你遇到的错误是因为CASE WHEN的THEN分支里的子查询返回了多个值。原代码的子查询没有关联主查询的账户标识(比如id或acct),会把所有满足transcode='67'和transnarrative='WITHDRAWAL FEES'的记录日期全部查出来,返回多行结果,但CASE WHEN的每个分支只能接收单个值,因此触发报错。
另外,原代码里的DISTINCT也无法保证只返回单个值——如果存在多个不同的日期符合条件,依然会返回多行。
修正方案
方案1:关联主查询+用MAX确保单个值
修改子查询,加入和主查询的关联条件,只针对当前账户查找符合条件的记录,再用MAX()直接获取最后一笔的日期,确保返回单个值:
-- 假设主查询的表名为main_table,包含acct和id字段 CASE WHEN acct = 'S8' THEN (SELECT MAX(t1.transprocessdate) FROM qpcureporting.dbo.acctran t1 WHERE t1.id = main_table.id -- 关联当前账户的id AND t1.transcode = '67' AND t1.transnarrative = 'WITHDRAWAL FEES') WHEN acct = 'S6' THEN (SELECT MAX(t1.transprocessdate) FROM qpcureporting.dbo.acctran t1 WHERE t1.id = main_table.id AND t1.transcode = '你的S6对应代码' -- 替换为S6的特定代码 AND t1.transnarrative = '你的S6对应描述') -- 替换为S6的特定描述 -- 其他账户类型同理 END AS Last_Specific_Fee_Date
方案2:用窗口函数提前标记最后一笔记录(更高效)
如果需要处理多种账户类型,用窗口函数先给每个账户+交易代码+描述的分组标记最后一行,再关联查询,避免多个子查询:
WITH Ranked_Trans AS ( SELECT acct, transprocessdate, transcode, transnarrative, -- 按账户、交易代码、描述分组,按日期倒序排名,最后一笔排第1 ROW_NUMBER() OVER (PARTITION BY acct, transcode, transnarrative ORDER BY transprocessdate DESC) AS rn FROM qpcureporting.dbo.acctran ) SELECT m.acct, -- 针对不同账户类型取对应的最后一笔日期 CASE WHEN m.acct = 'S8' THEN rt_S8.transprocessdate WHEN m.acct = 'S6' THEN rt_S6.transprocessdate -- 其他账户类型继续补充 END AS Last_Fee_Date FROM main_table m -- 关联S8对应的最后一笔记录 LEFT JOIN Ranked_Trans rt_S8 ON m.acct = rt_S8.acct AND rt_S8.transcode = '67' AND rt_S8.transnarrative = 'WITHDRAWAL FEES' AND rt_S8.rn = 1 -- 关联S6对应的最后一笔记录 LEFT JOIN Ranked_Trans rt_S6 ON m.acct = rt_S6.acct AND rt_S6.transcode = 'S6的代码' AND rt_S6.transnarrative = 'S6的描述' AND rt_S6.rn = 1 -- 其他账户类型的关联同理
内容的提问来源于stack exchange,提问作者user19614947
相关产品推荐
相关产品推荐

