我现在在做一个关于员工保险管理的东西 首先有个保险申请 保险申请里有两个主要的字段 开始时间和结束时间 现在要做一个统计 要求是将一个员工每个月的保险金额统计出来 但是有一个地方比较麻烦 就是开始时间到结束时间之间可能不是一个月 是多个月(2月份~5月份 这样也可以的) 但也有可能是一个月内有两次保险申请(比如月初申请 中途结束 月末又申请一回 他俩算一个月) 要统计每个月在保险方面消费的金额 这样的话 SQL语句怎么写?我不知道SQL语句里有没有类似的函数可以帮助到我 所以麻烦各位刚休假结束的大哥大姐了 我没说明白可以告诉我 我再补充
解决方案 »
- struts2和spring3整合项目,action无法调用业务逻辑组件的方法
- 常用的分页组件
- java中能生成饼状图,柱状图的控件
- Java中Collections的用法,求解!
- SSH代码生成器
- 小弟刚学完J2SE和JAVA WEB 和servlet相关知识,J2EE 知识看起来很多,,应该怎么入手啊?
- jquery 的ajax操作select标签出问题
- 打印PDF的问题,请进...
- 急■■■struts架构下FORM中的参数是如何传递到下个页面的啊???
- 请问开发java用什么工具好?谢谢!!是可视化的那种。谢谢。
- Spring事务管理, 异常
- [急]关于hibernate3.2+struts2查询问题
是 但是也有可能多个月份一次申请 也要给他分开 我不是很懂SQL 程序实现的话我想我能办到 但是不知道SQL咋写呢.. 过完年后 有点糊涂
统计的时候有些数据也需要统计 比如个人交纳或者企业交纳什么的 能放到SQL里计算的都放到这里计算 但是现在很明显有两种情况 所以这里我有点糊涂了..感谢蛋壳~
FROM 保险申请表 t
WHERE t.开始日期 = data1
AND t.结束日期 =data2
GROUP BY t.员工ID
DESC你看看这个是不是你想要的
TO_CHAR(t.保险申请时间,'yyyymm'),
SUM(t.保险金额)
FROM 保险申请表 t
WHERE t.开始日期 = data1
AND t.结束日期 =data2
GROUP BY t.员工ID ,TO_CHAR(t.保险申请时间,'yyyymm')
DESC看看这个吧 上面那个不算 需求没看全
2.考虑同一员工同一月有多次申请的情况,先把这些记录用distinct滤重
select 员工,保险申请(“yyyy-mm”格式),,sum(金额)
where 保险申请>=开始时间 and 保险申请<=开始时间
group by 员工,保险申请(“yyyy-mm”格式)
我不知道SQL中有没有类似的函数 还是我这类需求少见(我也听的莫名其妙的..)
这个不行 有些条件查询不出来假设您查询1月份的统计 那么1月份到3月份的记录可能就查不出来(保险申请>=开始时间 and 保险申请 <=开始时间?? 我不知道您是不是这个意思啊..) 以往的话光根据开始时间查询也行 但是这里结束时间是比较有用的
用一个sql可能写不出来 应该用存储过程来写
我记得以前有个人写过通用的行转列的存储过程 我找下
http://topic.csdn.net/u/20100109/13/6a10c168-f190-4766-b838-adbf03c4ac7b.html?64786我在尝试下能不能用一个sql写出来
union
select sum(金额),员工编号,2月 as 月份 from table1 where (startDate >= 2/1 and startDate <= 2/28) or (endDate >= 2/1 and endDate <= 2/28) group by 员工编号
union
.....
select sum(金额),员工编号,12月 as 月份 from table1 where (startDate >= 12/1 and startDate <= 12/31) or (endDate >= 12/1 and endDate <= 12/31) group by 员工编号
这个思路可以把每个月每个员工的保险金额取出来 楼主可以根据需求再筛选需要哪个月的比方说在程序里把金额为空的数据去掉!
这里只提供这么个思路 关于月末日的取法楼主可以百度下有很多的
union
select sum(金额),员工编号,2月 as 月份 from table1 where (startDate >= 2/1 and startDate <= 2/28) or (endDate >= 2/1 and endDate <= 2/28) or (startDate< 2/1 and endDate > 2/31) group by 员工编号
union
.....
select sum(金额),员工编号,12月 as 月份 from table1 where (startDate >= 12/1 and startDate <= 12/31) or (endDate >= 12/1 and endDate <= 12/31) or (startDate< 12/1 and endDate > 12/31) group by 员工编号
不好意思 上面那个少写了一个条件
需要用union 但其他的我不知道您是什么意思啊?
TO_CHAR(t.保险申请时间,'yyyymm'),
SUM(t.保险金额)
FROM 保险申请表 t
WHERE t.开始日期 = data1
AND t.结束日期 =data2
GROUP BY t.员工ID ,TO_CHAR(t.保险申请时间,'yyyymm')
DESC或者组合出来,用后台语言判断,如果本月没有值就显示同上个月的,这个代码很简单的吧 晕,给我分!!
----------------------------
1 500 1000
2 500 2000我不知道光用SQL语句能不能实现 所以我来问的问题 恩 这次估计比较详细了..
后台代码我觉得我可以实现(恩 应该可以...) 但是能SQL实现自然最好 我还得回去揣摩揣摩
那一个sql可以写出来 但是如果将来你向表中添加新的保险类别
那么这个sql也要跟着相应的变动
所以写过程是个好的选择
2.如果数据库中没有3月份的记录,则拿2月份或者之前的记录填补这个空缺。
是这个意思吧?SQL办不到这个。即使办到,也是非常困难且低效的。
你应该老实的把sum求出来,然后在程序中根据逻辑填补月份空缺。如果要像你想的那么做的话,可以改下数据库的结构,将申请event单独做一个管理表。event_id做主键。
然后如果某月没有申请的话,也插一条数据(event_id还是上一次的event_id)到数据库中。这个其实很好完成,写个存储过程,每月的最后一天运行。逐一查看每个员工是否在当月申请了保险。若无申请,则插一条记录。有则跳过。相比较而言,我倒是认为后一种办法更合理一些。
养老保险 、医疗保险和社会保险 三类
下面的这个大概应该是这样的 可能有些错误
因为没有环境 运行不了 大概思路是这样的
SELECT t.员工ID AS '员工id',
DECODE((t.开始日期 > data1 AND t.结束日期 > data2) ,t.保险金额,'') AS '养老保险',
DECODE((t.开始日期 > data1 AND t.结束日期 > data2) ,t.保险金额,'') AS '医疗保险',
DECODE((t.开始日期 > data1 AND t.结束日期 > data2) ,t.保险金额,'') AS '社会保险'
FROM 保险申请表 t
WHERE t.开始日期 > data1 --!你的查询条件的开始日期
GROUP BY t.员工ID ,TO_CHAR(t.开始日期,'yyyymm')
反正就是使用decode 对 01-12 月份 和 保险类别进行区分
可能需要decode的嵌套 很麻烦
大概就是这样的一个思路 下班了 祝你好运!
可以肯定像这样的需求数据库肯定是没有现成的函数的。
不过我第一想法是,这个用程序实现更合适,没必要在sql上死抠哇。
公司框架 用SQL语句弄的话会统一些 如果不行我会考虑程序的
2.不是 现在是 如果这个月存在两个保险申请 则合并成一条(统计嘛..) 如果说一个保险申请时间跨度为多个月 那么在显示统计结果的时候将这几个月所有的记录都给他显示这一条记录
简单点说 假设二个申请 1月1号到1月5号 1月6号到1月29号 这个就给他合成一条
如果说一个申请的时间跨度为 1月1号到5月5号 那么统计的时候 1月份到5月份都显示这条记录需求似乎不是很正确 如果SQL实现不了那我就程序了
动态生成sql的话,你可以用多个union把简单sql连接起来,可以实现。
每个简单sql仅查询一个月的记录。
吧一个sql 拆分开来
这样的实现decode 和 union 都实现不了你要的功能
一个sql不行
/**
* 获得员工保险统计记录(个人)
*
* @param String
* startDateText 开始时间 格式(yyyy-MM)
* @param String
* endDateText 结束时间 格式(yyyy-MM)
* @param String
* empId 人员ID
* @param String
* insureList 保险类别集合
*
* @return List<Object[]>
*/
@SuppressWarnings("unchecked")
public List<Object[]> getInsureCountList(String startDateText,
String endDateText, String empId, List<Insure> insureList)
throws Exception {
String basesql = "";// 最终执行的查询语句
String innersql = " select "; // 按月查询的查询语句 全部组合到一起就是最终执行的查询语句
List<String> dateList = getDateList(startDateText, endDateText);// 获得开始日期到结束日期之间所有的月份(每月的一号 如2010-01-01) // 循环类别生成该语句的列
for (Insure insure : insureList) {
innersql += ",sum(case when insurance.insid = " + insure.getId()
+ " then insurance.buckle else 0 end) as buckle_"
+ insure.getId() + ",sum(case when insurance.insid = "
+ insure.getId()
+ " then insurance.bucklecompany else 0 end) as buckleCompany_"
+ insure.getId();
}
innersql = innersql.replaceFirst(",", "");
innersql += " from hr_insurance insurance where insurance.empid = " + empId; // 加上员工的条件 这个不需要分组 // 根据所有的月份 不断的增加每个月份的SQL语句 下面关于日期判断的SQL可能有问题
for (int i = 0; i < (dateList.size() - 1); i++) {
basesql += innersql;
basesql += " and ((insurance.bookindate >= to_date('"
+ dateList.get(i)
+ "', 'yyyy-MM-dd') and insurance.overdate < to_date('"
+ dateList.get(i + 1)
+ "', 'yyyy-MM-dd')) or (insurance.bookindate >= to_date('"
+ dateList.get(i)
+ "', 'yyyy-MM-dd') and insurance.bookindate < to_date('"
+ dateList.get(i + 1)
+ "', 'yyyy-MM-dd')) or (insurance.overdate >= to_date('"
+ dateList.get(i)
+ "', 'yyyy-MM-dd') and insurance.overdate < to_date('"
+ dateList.get(i + 1)
+ "', 'yyyy-MM-dd')) or (insurance.bookindate <= to_date('"
+ dateList.get(i)
+ "', 'yyyy-MM-dd') and insurance.overdate >= to_date('"
+ dateList.get(i + 1) + "', 'yyyy-MM-dd'))) union ";
}
basesql += innersql;
basesql += " and ((insurance.bookindate >= to_date('" + dateList.get(0)
+ "', 'yyyy-MM-dd') and insurance.overdate < to_date('"
+ dateList.get(dateList.size() - 1)
+ "', 'yyyy-MM-dd')) or (insurance.bookindate >= to_date('"
+ dateList.get(0)
+ "', 'yyyy-MM-dd') and insurance.bookindate < to_date('"
+ dateList.get(dateList.size() - 1)
+ "', 'yyyy-MM-dd')) or (insurance.overdate >= to_date('"
+ dateList.get(0)
+ "', 'yyyy-MM-dd') and insurance.overdate < to_date('"
+ dateList.get(dateList.size() - 1)
+ "', 'yyyy-MM-dd')) or (insurance.bookindate <= to_date('"
+ dateList.get(0)
+ "', 'yyyy-MM-dd') and insurance.overdate >= to_date('"
+ dateList.get(dateList.size() - 1) + "', 'yyyy-MM-dd'))) ";// 全部月份的统计条件
return entityManager.queryListBySql(basesql);
}
上面的是代码 下面的是生成的SQL语句 我运行了 结果也不知道对错..恶心死我了 我时间判断那里好象不太对劲 bookindate 是保险申请时间 overdate 是保险结束时间
select sum(case
when insurance.insid = 161 then
insurance.buckle
else
0
end) as buckle_161,
sum(case
when insurance.insid = 161 then
insurance.bucklecompany
else
0
end) as buckleCompany_161,
sum(case
when insurance.insid = 141 then
insurance.buckle
else
0
end) as buckle_141,
sum(case
when insurance.insid = 141 then
insurance.bucklecompany
else
0
end) as buckleCompany_141,
sum(case
when insurance.insid = 142 then
insurance.buckle
else
0
end) as buckle_142,
sum(case
when insurance.insid = 142 then
insurance.bucklecompany
else
0
end) as buckleCompany_142,
sum(case
when insurance.insid = 143 then
insurance.buckle
else
0
end) as buckle_143,
sum(case
when insurance.insid = 143 then
insurance.bucklecompany
else
0
end) as buckleCompany_143,
sum(case
when insurance.insid = 144 then
insurance.buckle
else
0
end) as buckle_144,
sum(case
when insurance.insid = 144 then
insurance.bucklecompany
else
0
end) as buckleCompany_144,
sum(case
when insurance.insid = 145 then
insurance.buckle
else
0
end) as buckle_145,
sum(case
when insurance.insid = 145 then
insurance.bucklecompany
else
0
end) as buckleCompany_145,
sum(case
when insurance.insid = 146 then
insurance.buckle
else
0
end) as buckle_146,
sum(case
when insurance.insid = 146 then
insurance.bucklecompany
else
0
end) as buckleCompany_146
from hr_insurance insurance
where insurance.empid = 321
and ((insurance.bookindate >= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.overdate < to_date('2010-03-01', 'yyyy-MM-dd')) or
(insurance.bookindate >= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.bookindate < to_date('2010-03-01', 'yyyy-MM-dd')) or
(insurance.overdate >= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.overdate < to_date('2010-03-01', 'yyyy-MM-dd')) or
(insurance.bookindate <= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.overdate >= to_date('2010-03-01', 'yyyy-MM-dd')))
union
select sum(case
when insurance.insid = 161 then
insurance.buckle
else
0
end) as buckle_161,
sum(case
when insurance.insid = 161 then
insurance.bucklecompany
else
0
end) as buckleCompany_161,
sum(case
when insurance.insid = 141 then
insurance.buckle
else
0
end) as buckle_141,
sum(case
when insurance.insid = 141 then
insurance.bucklecompany
else
0
end) as buckleCompany_141,
sum(case
when insurance.insid = 142 then
insurance.buckle
else
0
end) as buckle_142,
sum(case
when insurance.insid = 142 then
insurance.bucklecompany
else
0
end) as buckleCompany_142,
sum(case
when insurance.insid = 143 then
insurance.buckle
else
0
end) as buckle_143,
sum(case
when insurance.insid = 143 then
insurance.bucklecompany
else
0
end) as buckleCompany_143,
sum(case
when insurance.insid = 144 then
insurance.buckle
else
0
end) as buckle_144,
sum(case
when insurance.insid = 144 then
insurance.bucklecompany
else
0
end) as buckleCompany_144,
sum(case
when insurance.insid = 145 then
insurance.buckle
else
0
end) as buckle_145,
sum(case
when insurance.insid = 145 then
insurance.bucklecompany
else
0
end) as buckleCompany_145,
sum(case
when insurance.insid = 146 then
insurance.buckle
else
0
end) as buckle_146,
sum(case
when insurance.insid = 146 then
insurance.bucklecompany
else
0
end) as buckleCompany_146
from hr_insurance insurance
where insurance.empid = 321
and ((insurance.bookindate >= to_date('2010-03-01', 'yyyy-MM-dd') and
insurance.overdate < to_date('2010-04-01', 'yyyy-MM-dd')) or
(insurance.bookindate >= to_date('2010-03-01', 'yyyy-MM-dd') and
insurance.bookindate < to_date('2010-04-01', 'yyyy-MM-dd')) or
(insurance.overdate >= to_date('2010-03-01', 'yyyy-MM-dd') and
insurance.overdate < to_date('2010-04-01', 'yyyy-MM-dd')) or
(insurance.bookindate <= to_date('2010-03-01', 'yyyy-MM-dd') and
insurance.overdate >= to_date('2010-04-01', 'yyyy-MM-dd')))
union
select sum(case
when insurance.insid = 161 then
insurance.buckle
else
0
end) as buckle_161,
sum(case
when insurance.insid = 161 then
insurance.bucklecompany
else
0
end) as buckleCompany_161,
sum(case
when insurance.insid = 141 then
insurance.buckle
else
0
end) as buckle_141,
sum(case
when insurance.insid = 141 then
insurance.bucklecompany
else
0
end) as buckleCompany_141,
sum(case
when insurance.insid = 142 then
insurance.buckle
else
0
end) as buckle_142,
sum(case
when insurance.insid = 142 then
insurance.bucklecompany
else
0
end) as buckleCompany_142,
sum(case
when insurance.insid = 143 then
insurance.buckle
else
0
end) as buckle_143,
sum(case
when insurance.insid = 143 then
insurance.bucklecompany
else
0
end) as buckleCompany_143,
sum(case
when insurance.insid = 144 then
insurance.buckle
else
0
end) as buckle_144,
sum(case
when insurance.insid = 144 then
insurance.bucklecompany
else
0
end) as buckleCompany_144,
sum(case
when insurance.insid = 145 then
insurance.buckle
else
0
end) as buckle_145,
sum(case
when insurance.insid = 145 then
insurance.bucklecompany
else
0
end) as buckleCompany_145,
sum(case
when insurance.insid = 146 then
insurance.buckle
else
0
end) as buckle_146,
sum(case
when insurance.insid = 146 then
insurance.bucklecompany
else
0
end) as buckleCompany_146
from hr_insurance insurance
where insurance.empid = 321
and ((insurance.bookindate >= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.overdate < to_date('2010-05-01', 'yyyy-MM-dd')) or
(insurance.bookindate >= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.bookindate < to_date('2010-05-01', 'yyyy-MM-dd')) or
(insurance.overdate >= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.overdate < to_date('2010-05-01', 'yyyy-MM-dd')) or
(insurance.bookindate <= to_date('2010-02-01', 'yyyy-MM-dd') and
insurance.overdate >= to_date('2010-05-01', 'yyyy-MM-dd')))
你这个sql执行过吗?
你看看如果表中的数据有10w以上的时候 你执行一次需要多少时间
我没看逻辑 你这么搞。 不要用union 和 case when
换成decode
decode 咋用?语句执行了 俩三月没问题 过了5个月 这TM给我卡的..
当表达式为真 返回结果1
否则 结果2
decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
resultMap="CMP_RAS_RAS_REMIT_ERROR.BaseResultMap"
parameterClass="java.util.Map">
SELECT * FROM (SELECT row_.*, rownum rownum_ FROM ( select *
from CMP_RAS.RAS_REMIT_ERROR where handle_type != '4'
<dynamic prepend="and">
<isNotNull prepend="AND" property="accountName">
ACCOUNT_NAME like '%'||#accountName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="accountNo">
ACCOUNT_NO like '%'||#accountNo:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="amount">
AMOUNT=#amount:DECIMAL#
</isNotNull>
<isNotNull prepend="AND" property="matchName">
MATCH_NAME like '%'||#matchName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="note">
NOTE like '%'||#note:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="beginDate">
to_char(TRAN_DATE,'yyyy-MM-dd HH:mm:SS') >= #beginDate#
</isNotNull>
<isNotNull prepend="AND" property="endDate">
to_char(TRAN_DATE,'yyyy-MM-dd HH:mm:SS')<![CDATA[ <=]]>
#endDate#
</isNotNull>
</dynamic> minus select r.* from (
(select t1.* from CMP_RAS.RAS_REMIT_ERROR t1
inner join CMP_RAS.RAS_ORDER_INFO t2 on (t1.ACCOUNT_NAME =
t2.ENT_FULL_NAME and
<![CDATA[t1.AMOUNT < t2.PAY_SUM]]>) where t1.handle_type != '4'
and t1.match_name is null
<dynamic prepend="and">
<isNotNull prepend="AND" property="accountName">
t1.ACCOUNT_NAME like '%'||#accountName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="accountNo">
t1.ACCOUNT_NO like '%'||#accountNo:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="amount">
t1.AMOUNT=#amount:DECIMAL#
</isNotNull>
<isNotNull prepend="AND" property="matchName">
t1.MATCH_NAME like '%'||#matchName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="note">
t1.NOTE like '%'||#note:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="beginDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS') >= #beginDate#
</isNotNull>
<isNotNull prepend="AND" property="endDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS')<![CDATA[ <=]]> #endDate#
</isNotNull>
</dynamic>)
union
(select t1.* from CMP_RAS.RAS_REMIT_ERROR t1
inner join CMP_RAS.RAS_ORDER_INFO t2 on (t1.match_name =
t2.ENT_FULL_NAME and
<![CDATA[t1.AMOUNT < t2.PAY_SUM]]>) where t1.handle_type != '4'
and t1.match_name is not null
<dynamic prepend="and">
<isNotNull prepend="AND" property="accountName">
t1.ACCOUNT_NAME like '%'||#accountName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="accountNo">
t1.ACCOUNT_NO like '%'||#accountNo:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="amount">
t1.AMOUNT=#amount:DECIMAL#
</isNotNull>
<isNotNull prepend="AND" property="matchName">
t1.MATCH_NAME like '%'||#matchName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="note">
t1.NOTE like '%'||#note:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="beginDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS') >= #beginDate#
</isNotNull>
<isNotNull prepend="AND" property="endDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS')<![CDATA[ <=]]> #endDate#
</isNotNull>
</dynamic>)
) r where r.ACCOUNT_NAME in (select t.ACCOUNT_NAME_TEMP from ((select
t1.ACCOUNT_NAME as ACCOUNT_NAME_TEMP,t1.* from CMP_RAS.RAS_REMIT_ERROR t1 inner join
CMP_RAS.RAS_ORDER_INFO t2 on (t1.ACCOUNT_NAME = t2.ENT_FULL_NAME
and
<![CDATA[t1.AMOUNT < t2.PAY_SUM]]>) where t1.handle_type != '4'
and t1.match_name is null
<dynamic prepend="and">
<isNotNull prepend="AND" property="accountName">
t1.ACCOUNT_NAME like '%'||#accountName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="accountNo">
t1.ACCOUNT_NO like '%'||#accountNo:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="amount">
t1.AMOUNT=#amount:DECIMAL#
</isNotNull>
<isNotNull prepend="AND" property="matchName">
t1.MATCH_NAME like '%'||#matchName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="note">
t1.NOTE like '%'||#note:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="beginDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS') >= #beginDate#
</isNotNull>
<isNotNull prepend="AND" property="endDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS')<![CDATA[ <=]]> #endDate#
</isNotNull>
</dynamic>)
union
(select t1.match_name as ACCOUNT_NAME_TEMP,t1.* from CMP_RAS.RAS_REMIT_ERROR t1
inner join CMP_RAS.RAS_ORDER_INFO t2 on (t1.match_name =
t2.ENT_FULL_NAME and
<![CDATA[t1.AMOUNT < t2.PAY_SUM]]>) where t1.handle_type != '4'
and t1.match_name is not null
<dynamic prepend="and">
<isNotNull prepend="AND" property="accountName">
t1.ACCOUNT_NAME like '%'||#accountName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="accountNo">
t1.ACCOUNT_NO like '%'||#accountNo:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="amount">
t1.AMOUNT=#amount:DECIMAL#
</isNotNull>
<isNotNull prepend="AND" property="matchName">
t1.MATCH_NAME like '%'||#matchName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="note">
t1.NOTE like '%'||#note:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="beginDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS') >= #beginDate#
</isNotNull>
<isNotNull prepend="AND" property="endDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS')<![CDATA[ <=]]> #endDate#
</isNotNull>
</dynamic>)
) t group by t.ACCOUNT_NAME_TEMP having count(t.ACCOUNT_NAME_TEMP) > 1)
or
r.match_name in (select t.ACCOUNT_NAME_TEMP from ((select
t1.ACCOUNT_NAME as ACCOUNT_NAME_TEMP,t1.* from CMP_RAS.RAS_REMIT_ERROR t1 inner join
CMP_RAS.RAS_ORDER_INFO t2 on (t1.ACCOUNT_NAME = t2.ENT_FULL_NAME
and
<![CDATA[t1.AMOUNT < t2.PAY_SUM]]>) where t1.handle_type != '4'
and t1.match_name is null
<dynamic prepend="and">
<isNotNull prepend="AND" property="accountName">
t1.ACCOUNT_NAME like '%'||#accountName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="accountNo">
t1.ACCOUNT_NO like '%'||#accountNo:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="amount">
t1.AMOUNT=#amount:DECIMAL#
</isNotNull>
<isNotNull prepend="AND" property="matchName">
t1.MATCH_NAME like '%'||#matchName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="note">
t1.NOTE like '%'||#note:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="beginDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS') >= #beginDate#
</isNotNull>
<isNotNull prepend="AND" property="endDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS')<![CDATA[ <=]]> #endDate#
</isNotNull>
</dynamic>)
union
(select t1.match_name as ACCOUNT_NAME_TEMP,t1.* from CMP_RAS.RAS_REMIT_ERROR t1
inner join CMP_RAS.RAS_ORDER_INFO t2 on (t1.match_name =
t2.ENT_FULL_NAME and
<![CDATA[t1.AMOUNT < t2.PAY_SUM]]>) where t1.handle_type != '4'
and t1.match_name is not null
<dynamic prepend="and">
<isNotNull prepend="AND" property="accountName">
t1.ACCOUNT_NAME like '%'||#accountName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="accountNo">
t1.ACCOUNT_NO like '%'||#accountNo:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="amount">
t1.AMOUNT=#amount:DECIMAL#
</isNotNull>
<isNotNull prepend="AND" property="matchName">
t1.MATCH_NAME like '%'||#matchName:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="note">
t1.NOTE like '%'||#note:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend="AND" property="beginDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS') >= #beginDate#
</isNotNull>
<isNotNull prepend="AND" property="endDate">
to_char(t1.TRAN_DATE,'yyyy-MM-dd HH:mm:SS')<![CDATA[ <=]]> #endDate#
</isNotNull>
</dynamic>)
) t group by t.ACCOUNT_NAME_TEMP having count(t.ACCOUNT_NAME_TEMP) > 1)
<![CDATA[
)
row_ WHERE rownum <=#endRecord#
)
WHERE rownum_ >#startRecord#
]]>
</select>
这个东西对性能 影响很大
用decode主要是 弃用union
如果你使用了 union 就相当于执行了 多个查询这样的时间当然多了 decode 是对你的结果集进行筛选
这样它就相当于查询了一次 其他操作都是对这一次结果的操作
不涉及对数据的查询
然后你在java代码中 拼 select 后面decode函数的个数
这个个数应该和你的union个数相当
那么你用个where 就是把所有满足结果的都查询出来了
然后在select 后面用 decode()函数把这个所有满足的结果集通过条件判断在区分开这样不就达到你的目的了 不然的话
你如果查询 开始时间 2000.1结束时间2010.1 这中间有10年 120个月
你难道还要120union语句连接到一起吗?
内层是 保险分类的个数这就需要你在拼这个最大的sql之前 先把间隔的月数 和 保险分类的个数计算和读取出来这个sql的拼写有点 二维数组的味道希望这么说能对你有点帮助
不过就算这么些了 这个查询在大数据量的时候性能还是有瓶颈的 这个性能问题只能通过应用去限制了 sql能做到的就这么多
这就不是SQL干的活嘛。
应该是某些情况被你忽略了 建议你把sql语句放到toad里面
然后把语句拆开 排查是哪部分问题好 不给ls分 那给lx吧 我是lx 哈哈。
HashMap<Month,<HashMap<保险ID,保险数据>>的HASHMAP 过程全部设计好谢谢几位大哥的指点 小的膜拜