SELECT ckd.FFCKD_ID,
         COUNT (DISTINCT (a.XCRZ_ID)) XCCSZS,
         COUNT (DISTINCT (x.XCRZ_ID)) XCCSDY,
         COUNT (DISTINCT (y.XCRZ_ID)) XCCSFDY
    FROM SS_FFCKD ckd,
             (SELECT FFCKD_ID,XCRZ_ID
               FROM TEST111 
               WHERE TO_CHAR (Xc_Sj, 'YYYYMMDD') BETWEEN 20160101 AND 2016013) a
             (SELECT FFCKD_ID,XCRZ_ID 
               FROM TEST111 
               WHERE TO_CHAR (Xc_Sj, 'YYYYMMDD') BETWEEN 20160101 AND 2016013 
                   AND TO_CHAR (create_time, 'YYYYMMDD') BETWEEN 20160101 AND 20160130) x,
             (SELECT FFCKD_ID,XCRZ_ID 
               FROM TEST111 
               WHERE TO_CHAR (Xc_Sj, 'YYYYMMDD') BETWEEN 20160101 AND 2016013 
                   AND (TO_CHAR (create_time, 'YYYYMMDD') < 20160101 OR TO_CHAR (create_time, 'YYYYMMDD') > 20160130)) y
  WHERE TO_CHAR (ckd.CREATE_TIME, 'YYYYMMDD') < 20160101
         AND ckd.FFCKD_ID = a.FFCKD_ID(+)
         AND ckd.FFCKD_ID = x.FFCKD_ID(+)
         AND ckd.FFCKD_ID = y.FFCKD_ID(+)
         AND ckd.XCFS_DM = 1     
  GROUP BY FFCKD_ID
需求:
只扫描一次TEST111 表
不需要扫描查询3次TEST111这张表,得到相同结果

解决方案 »

  1.   

    利用case when去改写sql
      

  2.   

    select bz,count(distinct XCRZ_ID) from (select ckd.FFCKD_ID,XCRZ_ID,case when TO_CHAR (create_time, 'YYYYMMDD') BETWEEN 20160101 AND 20160130 then 0 esle 1 end bz from 
    SS_FFCKD ckd,
    TEST111 a 
    where 
    ckd.FFCKD_ID = a.FFCKD_ID(+) and 
    TO_CHAR (Xc_Sj, 'YYYYMMDD') BETWEEN 20160101 AND 2016013 AND 
    ckd.XCFS_DM = 1) group by ckd.FFCKD_ID,bz;bz= 0 是代表 TO_CHAR (create_time, 'YYYYMMDD') BETWEEN 20160101 AND 20160130;
    bz= 1 是代表 TO_CHAR (create_time, 'YYYYMMDD') < 20160101 OR TO_CHAR (create_time, 'YYYYMMDD') > 20160130然后在通过with as去得到你想要的结果
      

  3.   

    用WITH AS
    是个不错的方法,可以试试