记一次PageHelper分页查询出现的去重失效问题

背景

单表查询福利明细数据

一个人员的福利数据明细对应多个明细类别行

例如:

​    张三(项目一):

​        社保:

            个人缴纳: xxx

            公司缴纳: xxx

        公积金:

​            个人缴纳: xxx

            公司缴纳: xxx

表结构示例如下:

cPersonName cProgramCode cBoonCode iPersonalPay iCompanyPay
张三 01 001(社保) 300 600
张三 01 002(公积金) 300 300

预期结果

cPersonName cProgramCode 其他信息列
张三 01

实际结果

cPersonName cProgramCode 其他信息列
张三 01 xxx
张三 01 xxx

Mapper如下

<select id="findBoonDetails" parameterType="cn.apcinfo.salary.query.boon.BoonListCondition" resultMap="boonMainMap">
SELECT 
	DISTINCT d.cDepCode as cDeptCode,d.cDepName as cDeptName,[iYear],	
	[iMonth],bd.cBoonProgram,wp.cprjname as cProgramName,cPayType as payType,
	CASE cPayType WHEN 0 THEN '缴交' ELSE '补缴' END AS cPayType,bd.cPsnNum,p.cPsn_Name,
	CASE iStatus WHEN 1 THEN '待处理' WHEN 2 THEN '已审核' 
	WHEN 3 THEN '已退回' ELSE '已撤销' END AS iStatus
FROM boon_data bd
JOIN ${ufname}..Department d ON bd.cDeptCode = d.cDepCode
JOIN ${ufname}..hr_wm_project wp ON bd.cBoonProgram = wp.cprjcode
JOIN ${ufname}..hr_hi_person p ON p.cPsn_Num = bd.cPsnNum
WHERE 1=1
ORDER BY [cDeptCode],[iYear],[iMonth],[cBoonProgram],[cPayType],[cPsnNum],[cBoonCode]
</select>

注意:以上SQL语句直接放到SQL查询分析器中报错如下:
在这里插入图片描述

但是使用PageHelper却不会报错,只会产生重复的数据行。
查看控制台打印的SQL语句如下:

-- 查询总数据条数SQL
SELECT count(0) FROM (
    
    SELECT 
    	DISTINCT d.cDepCode AS cDeptCode, d.cDepName AS cDeptName, [iYear], [iMonth], 			bd.cBoonProgram, wp.cprjname AS cProgramName, cPayType AS payType, 
    	CASE cPayType WHEN 0 THEN '缴交' ELSE '补缴' END AS cPayType, bd.cPsnNum, 				p.cPsn_Name, 
    	CASE iStatus WHEN 1 THEN '待处理' WHEN 2 THEN '已审核' WHEN 3 THEN '已退回' ELSE '已撤销' END AS iStatus 
		FROM boon_data bd JOIN UFDATA_800_2019..Department d 
    	ON bd.cDeptCode = d.cDepCode 			
    	JOIN ${ufname}..hr_wm_project wp 
    	ON bd.cBoonProgram = wp.cprjcode 
    	JOIN ${ufname}..hr_hi_person p 
    	ON p.cPsn_Num = bd.cPsnNum 
    	WHERE 1 = 1 AND cBoonProgram = ? AND cPayType = ?

) table_count 

-- 分页查询SQL
SELECT TOP 10 cDeptCode, cDeptName, [iYear], [iMonth], cBoonProgram, cProgramName, payType, cPayType, cPsnNum, cPsn_Name, iStatus FROM (
    
    SELECT ROW_NUMBER() OVER (ORDER BY ROW_ALIAS_1, [iYear], [iMonth], ROW_ALIAS_2, ROW_ALIAS_3, ROW_ALIAS_4,ROW_ALIAS_5) PAGE_ROW_NUMBER, cDeptCode, cDeptName, [iYear], [iMonth], cBoonProgram, cProgramName, payType, cPayType, cPsnNum, cPsn_Name, iStatus FROM (
        
        SELECT 
        	DISTINCT d.cDepCode AS cDeptCode, d.cDepName AS cDeptName, [iYear], [iMonth],
			bd.cBoonProgram, wp.cprjname AS cProgramName, cPayType AS payType, 
        	CASE cPayType WHEN 0 THEN '缴交' ELSE '补缴' END AS cPayType, bd.cPsnNum, 				p.cPsn_Name, CASE iStatus WHEN 1 THEN '待处理' WHEN 2 THEN '已审核' WHEN 3 THEN '已退回' ELSE '已撤销' END AS iStatus, 
        	[cDeptCode] AS ROW_ALIAS_1, [cBoonProgram] AS ROW_ALIAS_2, [cPayType] AS ROW_ALIAS_3, [cPsnNum] AS ROW_ALIAS_4 
        	FROM boon_data bd JOIN UFDATA_800_2019..Department d 
        	ON bd.cDeptCode = d.cDepCode JOIN UFDATA_800_2019..hr_wm_project wp 
        	ON bd.cBoonProgram = wp.cprjcode JOIN UFDATA_800_2019..hr_hi_person p 
        	ON p.cPsn_Num = bd.cPsnNum WHERE 1 = 1 
        	AND cBoonProgram = ? AND cPayType = ?) 
    AS PAGE_TABLE_ALIAS) 
    AS PAGE_TABLE_ALIAS 
    WHERE PAGE_ROW_NUMBER > 0 ORDER BY PAGE_ROW_NUMBER 

观察如上两条SQL语句不难发现:

  1. 查询数据条数的SQL中,PageHelper移除了Order By子句

  2. 分页查询数据的SQL中,PageHelper将Order By子句修改成了

    ROW_NUMBER() OVER (ORDER BY ROW_ALIAS_1, [iYear], [iMonth], ROW_ALIAS_2, ROW_ALIAS_3, ROW_ALIAS_4)
    

问题就在这里,PageHelper直接将OrderBy子句中需要且结果字段中不存在(别名匹配的不算)的列拼接到了原SQL末尾

[cDeptCode] AS ROW_ALIAS_1, [cBoonProgram] AS ROW_ALIAS_2, [cPayType] AS ROW_ALIAS_3, [cPsnNum] AS ROW_ALIAS_4,[cBoonCode] AS ROW_ALIAS_5 

但是我原本的结果中并没有cBoonCode字段,所以取到的结果集就表现成了去重失效。

总结:遇到这样的问题,还是要细心检查SQL语句(我是直接拷贝的另一条SQL,改了一下,结果排序字段忘记删了),查看控制台输出的SQL与原SQL语句有什么区别,将处理后的SQL和原SQL语句认真比对。

你可能感兴趣的:(Mybatis,相关)