各表主键:
表M_PSNMONTHACCOUNTRECORD的主键;表M_SJ_M_PERSON主键STATMONTH, PSNSN;表M_SJ_M_CORPORATION主键STATMONTH, CORPSN。                        
SQL语句:
SELECT *
  FROM (SELECT 16 AS AGE,
               A.FEEMONTH,
               B.FEEAREA,
               C.CORPTYPE,
               COUNT(B.PSNSN),
               SUM(A.FEEBASE)
          FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
               M_SJ_M_PERSON                         B,
               M_SJ_M_CORPORATION                    C
         WHERE A.PSNSN = B.PSNSN
           AND B.STATMONTH = C.STATMONTH
           AND B.CORPSN = C.CORPSN
           AND B.AGE <= 16
           AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
         GROUP BY A.FEEMONTH, B.FEEAREA, C.CORPTYPE
        UNION
        SELECT B.AGE,
               A.FEEMONTH,
               B.FEEAREA,
               C.CORPTYPE,
               COUNT(B.PSNSN),
               SUM(A.FEEBASE)
          FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
               M_SJ_M_PERSON                         B,
               M_SJ_M_CORPORATION                    C
         WHERE A.PSNSN = B.PSNSN
           AND B.STATMONTH = C.STATMONTH
           AND B.CORPSN = C.CORPSN
           AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
         GROUP BY B.AGE, A.FEEMONTH, B.FEEAREA, C.CORPTYPE
        HAVING B.AGE BETWEEN 17 AND 64
        UNION
        SELECT 65 AS AGE,
               A.FEEMONTH,
               B.FEEAREA,
               C.CORPTYPE,
               COUNT(B.PSNSN),
               SUM(A.FEEBASE)
          FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
               M_SJ_M_PERSON                         B,
               M_SJ_M_CORPORATION                    C
         WHERE A.PSNSN = B.PSNSN
           AND B.STATMONTH = C.STATMONTH
           AND B.CORPSN = C.CORPSN
           AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
           AND B.AGE >= 65
         GROUP BY B.FEEAREA, A.FEEMONTH, B.FEEAREA, C.CORPTYPE)

解决方案 »

  1.   

    1、把UNION 想办法去掉
    2、GROUP尽量少用
      

  2.   

    分组GROUP是必须的,请问该语句有没有优化的空间,谢谢!
      

  3.   

    优化如下:
    SELECT   case when A.AGE <= 16 then 16 
                  when A.AGE >= 65 then 65
                  else A.AGE end age,
                   A.FEEMONTH,
                   B.FEEAREA,
                   C.CORPTYPE,
                   COUNT(B.PSNSN),
                   SUM(A.FEEBASE)
              FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
                   M_SJ_M_PERSON                         B,
                   M_SJ_M_CORPORATION                    C
             WHERE A.PSNSN = B.PSNSN
               AND B.STATMONTH = C.STATMONTH
               AND B.CORPSN = C.CORPSN
               AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
             GROUP BY  case when A.AGE <= 16 then 16 
                  when A.AGE >= 65 then 65,
                  else A.AGE end,A.FEEMONTH, B.FEEAREA, C.CORPTYPE
             
      

  4.   

    when A.AGE >= 65 then 65, 这里多了个,号。去掉下
      

  5.   

    1,Oracle从右到左处理From子句中的表名,所以在From子句中包含多个表的情况下,将记录最少的表放在最后
    2, not in 不走索引,可以试着改用 not exists