我现在在做一个关于员工保险管理的东西 首先有个保险申请 保险申请里有两个主要的字段 开始时间和结束时间 现在要做一个统计 要求是将一个员工每个月的保险金额统计出来 但是有一个地方比较麻烦 就是开始时间到结束时间之间可能不是一个月 是多个月(2月份~5月份 这样也可以的) 但也有可能是一个月内有两次保险申请(比如月初申请 中途结束 月末又申请一回 他俩算一个月) 要统计每个月在保险方面消费的金额 这样的话 SQL语句怎么写?我不知道SQL语句里有没有类似的函数可以帮助到我 所以麻烦各位刚休假结束的大哥大姐了 我没说明白可以告诉我 我再补充

解决方案 »

  1.   

    如果只是要查申请记录的次数的话,你就count(*)然后按月份分组就行了
      

  2.   


    是 但是也有可能多个月份一次申请 也要给他分开 我不是很懂SQL 程序实现的话我想我能办到 但是不知道SQL咋写呢.. 过完年后 有点糊涂
    统计的时候有些数据也需要统计 比如个人交纳或者企业交纳什么的 能放到SQL里计算的都放到这里计算 但是现在很明显有两种情况 所以这里我有点糊涂了..感谢蛋壳~
      

  3.   

    SELECT SUM(t.保险金额)
    FROM  保险申请表 t
    WHERE t.开始日期 = data1
      AND t.结束日期 =data2
    GROUP BY t.员工ID
    DESC你看看这个是不是你想要的
      

  4.   

    个人感觉,sql的目的就是为了查询出员工申请保险的月份有多少(是要去重复的),至于统计的活,在显示的时候做就好了!
      

  5.   

    SELECT t.员工ID,
       TO_CHAR(t.保险申请时间,'yyyymm'),
       SUM(t.保险金额)
    FROM  保险申请表 t
    WHERE t.开始日期 = data1
      AND t.结束日期 =data2
    GROUP BY t.员工ID ,TO_CHAR(t.保险申请时间,'yyyymm')
    DESC看看这个吧  上面那个不算  需求没看全
      

  6.   

    先“distinct 员工,月”把同一月的同一员工多次申请虑重, 然后group by月就行了。
      

  7.   

    1.如果没有一个月多次申请的情况,你要的就是每月有多少申请,这个 group by 月就行了。
    2.考虑同一员工同一月有多次申请的情况,先把这些记录用distinct滤重
      

  8.   


    select 员工,保险申请(“yyyy-mm”格式),,sum(金额)
     where 保险申请>=开始时间 and 保险申请<=开始时间
    group by 员工,保险申请(“yyyy-mm”格式)
      

  9.   

    我看明白了 我也告诉他了 满足条件的要显示 其实我现在貌似能解释下重点了一条语句中 一条记录可能分成多条记录 而多条记录可以合并成一条记录 
    我不知道SQL中有没有类似的函数 还是我这类需求少见(我也听的莫名其妙的..)
      

  10.   


    这个不行 有些条件查询不出来假设您查询1月份的统计 那么1月份到3月份的记录可能就查不出来(保险申请>=开始时间 and 保险申请 <=开始时间?? 我不知道您是不是这个意思啊..) 以往的话光根据开始时间查询也行 但是这里结束时间是比较有用的 
      

  11.   

    挺难的  这个有点类似于动态的行转列问题了
    用一个sql可能写不出来  应该用存储过程来写
    我记得以前有个人写过通用的行转列的存储过程 我找下
    http://topic.csdn.net/u/20100109/13/6a10c168-f190-4766-b838-adbf03c4ac7b.html?64786我在尝试下能不能用一个sql写出来
      

  12.   

    select sum(金额),员工编号,1月 as 月份 from table1 where (startDate >= 1/1 and startDate <= 1/31) or (endDate >= 1/1 and endDate <= 1/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) 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 员工编号
    这个思路可以把每个月每个员工的保险金额取出来 楼主可以根据需求再筛选需要哪个月的比方说在程序里把金额为空的数据去掉!
    这里只提供这么个思路 关于月末日的取法楼主可以百度下有很多的 
      

  13.   

    select sum(金额),员工编号,1月 as 月份 from table1 where (startDate >= 1/1 and startDate <= 1/31) or (endDate >= 1/1 and endDate <= 1/31) or (startDate< 1/1 and endDate > 1/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 员工编号
    不好意思 上面那个少写了一个条件 
      

  14.   


    需要用union 但其他的我不知道您是什么意思啊?
      

  15.   

    SELECT t.员工ID,
           TO_CHAR(t.保险申请时间,'yyyymm'),
           SUM(t.保险金额)
    FROM  保险申请表 t
    WHERE t.开始日期 = data1
          AND t.结束日期 =data2
    GROUP BY t.员工ID ,TO_CHAR(t.保险申请时间,'yyyymm')
    DESC或者组合出来,用后台语言判断,如果本月没有值就显示同上个月的,这个代码很简单的吧 晕,给我分!!
      

  16.   

    我重新说下需求 按照员工统计该员工在一个时间段内交纳的保险 这个保险分类别 比如医疗保险 养老保险社会保险等首先有一个条件 在同类别的保险中 比如第一条记录是1-7月 下条记录就必须从8月开始 这里不存在交集但是不同类别就不一样了 比如说医疗保险是从1-7月 而养老保险是从5-12月 他们是存在于一个表中 只是用一个保险类别跟他们区分开这样的话 我就有了个想法 就是将所有的记录都按月分开 同一个月的合并到一起 不是一个月的分成应该有的月数 于是我想象的表格是月份 养老保险 医疗保险...
    ----------------------------
     1    500     1000
     2    500     2000我不知道光用SQL语句能不能实现 所以我来问的问题 恩 这次估计比较详细了..
      

  17.   


    后台代码我觉得我可以实现(恩 应该可以...) 但是能SQL实现自然最好 我还得回去揣摩揣摩
      

  18.   

    如果你的保险类别的种类固定的话
    那一个sql可以写出来  但是如果将来你向表中添加新的保险类别
    那么这个sql也要跟着相应的变动
    所以写过程是个好的选择
      

  19.   

    1.每个月都要有记录。
    2.如果数据库中没有3月份的记录,则拿2月份或者之前的记录填补这个空缺。
    是这个意思吧?SQL办不到这个。即使办到,也是非常困难且低效的。
    你应该老实的把sum求出来,然后在程序中根据逻辑填补月份空缺。如果要像你想的那么做的话,可以改下数据库的结构,将申请event单独做一个管理表。event_id做主键。
    然后如果某月没有申请的话,也插一条数据(event_id还是上一次的event_id)到数据库中。这个其实很好完成,写个存储过程,每月的最后一天运行。逐一查看每个员工是否在当月申请了保险。若无申请,则插一条记录。有则跳过。相比较而言,我倒是认为后一种办法更合理一些。
      

  20.   

    假设只有
    养老保险 、医疗保险和社会保险 三类
    下面的这个大概应该是这样的  可能有些错误
    因为没有环境  运行不了  大概思路是这样的
    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')
      

  21.   

    这个又问题 
    反正就是使用decode 对 01-12 月份 和 保险类别进行区分
    可能需要decode的嵌套 很麻烦
    大概就是这样的一个思路  下班了 祝你好运!
      

  22.   

    今天上午看了半天,只看懂了需求,但sql语句也不会写,我的sql水平也只够最简单的增删查改。
    可以肯定像这样的需求数据库肯定是没有现成的函数的。
    不过我第一想法是,这个用程序实现更合适,没必要在sql上死抠哇。
      

  23.   


    公司框架 用SQL语句弄的话会统一些 如果不行我会考虑程序的
      

  24.   

    1.每个月不是都要有记录 现在做的是统计 如果那个月没记录也算种记录
    2.不是 现在是 如果这个月存在两个保险申请 则合并成一条(统计嘛..) 如果说一个保险申请时间跨度为多个月 那么在显示统计结果的时候将这几个月所有的记录都给他显示这一条记录
    简单点说 假设二个申请 1月1号到1月5号 1月6号到1月29号 这个就给他合成一条
    如果说一个申请的时间跨度为 1月1号到5月5号 那么统计的时候 1月份到5月份都显示这条记录需求似乎不是很正确 如果SQL实现不了那我就程序了
      

  25.   

    明白你的意思了,关键要看申请起始时间,按照起始时间重新组合数据。
    动态生成sql的话,你可以用多个union把简单sql连接起来,可以实现。
    每个简单sql仅查询一个月的记录。
      

  26.   

    如果你不想写存储过程 那就用程序吧
    吧一个sql 拆分开来
    这样的实现decode 和 union 都实现不了你要的功能
    一个sql不行
      

  27.   

    哪里不明白呢 首先肯定是要一个月一个月的分开取再union起来 这个没问题吧 sum(金额)是解决一个月内申请了2次的问题 然后就是日期区间的事了吧 起始时间在这个月里或者结束时间在这个月里或者这个月在起始时间和结束时间中间 你在纸上画画区间就知道了
      

  28.   


    /**
     * 获得员工保险统计记录(个人)
     * 
     * @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 是保险结束时间
      

  29.   


    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')))
      

  30.   


    你这个sql执行过吗?
    你看看如果表中的数据有10w以上的时候 你执行一次需要多少时间
    我没看逻辑  你这么搞。 不要用union 和 case when
    换成decode 
      

  31.   


    decode 咋用?语句执行了 俩三月没问题 过了5个月 这TM给我卡的..
      

  32.   

    decode(表达式,结果1,结果2)
    当表达式为真  返回结果1
    否则 结果2
      

  33.   

    记错了 。
    decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
      

  34.   

    http://www.cnblogs.com/ZHF/archive/2008/09/12/1289619.html你看看这个 
      

  35.   

    看看我的  与楼主无关啊<select id="CMP_RAS_RAS_REMIT_ERROR.selectSpliteRasRemitErrorsByMap"
    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>
      

  36.   

    把case换成这个效率就会提高? 现在查询没那么恐怖 但是我一点PL/SQL的优化语句就得等30多秒
      

  37.   

    受教了  下次我也一定用 decode
      

  38.   

    我建议你拆分成 2个 sql 语句来写 
      

  39.   

    你现在使用union 这个查询结果集的 连接
    这个东西对性能 影响很大  
    用decode主要是 弃用union 
    如果你使用了 union 就相当于执行了 多个查询这样的时间当然多了  decode 是对你的结果集进行筛选
    这样它就相当于查询了一次  其他操作都是对这一次结果的操作
    不涉及对数据的查询  
      

  40.   

    其实 就是只有一个where就可以了
    然后你在java代码中 拼 select 后面decode函数的个数 
    这个个数应该和你的union个数相当
      

  41.   

    把连接起来的结果集用一个WHERE好象可以 但是我用union是为了连接结果集啊 还是不明白 我太笨了...后悔当初不学SQL ..
      

  42.   

    你用union是把满足个个时间段的条件分开查出来后 连接到一起
    那么你用个where 就是把所有满足结果的都查询出来了
    然后在select 后面用 decode()函数把这个所有满足的结果集通过条件判断在区分开这样不就达到你的目的了  不然的话
    你如果查询  开始时间 2000.1结束时间2010.1 这中间有10年  120个月
    你难道还要120union语句连接到一起吗?
      

  43.   

    decode肯定是要嵌套的  外城decode的个数是 开始时间和结束时间之间间隔的月数
    内层是 保险分类的个数这就需要你在拼这个最大的sql之前 先把间隔的月数 和 保险分类的个数计算和读取出来这个sql的拼写有点 二维数组的味道希望这么说能对你有点帮助
    不过就算这么些了  这个查询在大数据量的时候性能还是有瓶颈的 这个性能问题只能通过应用去限制了  sql能做到的就这么多 
      

  44.   

    楼主,你把sql变成了折磨服务器的工具。
    这就不是SQL干的活嘛。
      

  45.   

    那就是你的sql语句的查询条件没限制好
    应该是某些情况被你忽略了  建议你把sql语句放到toad里面
    然后把语句拆开  排查是哪部分问题好  不给ls分  那给lx吧  我是lx  哈哈。
      

  46.   

    明天上午结帖 我结束了 决定用程序去完成 大致思路是 保存个
    HashMap<Month,<HashMap<保险ID,保险数据>>的HASHMAP 过程全部设计好谢谢几位大哥的指点 小的膜拜