表C 结构
cid        cdate                 cvalue    ctype
1       2007-11-8 8:40:36         21         0 
2       2007-10-8 8:40:36         0          1
3       2007-9-8 8:40:36          13         0
4       2007-8-8 8:40:36          21         0
5       2007-7-8 8:40:36          55         0
6       2007-6-8 8:40:36          3          0
7       2007-5-8 8:40:36          2          0
8       2007-4-8 8:40:36          0          0
9       2007-3-8 8:40:36          0          0
10      2007-2-8 8:40:36          21         1比如查询2月到11月的数据,并把时间在3个月前且cvalue是0的数据排除
需要得到的结构如下:
1       2007-11-8 8:40:36         21         0
3       2007-9-8 8:40:36          13         0
4       2007-8-8 8:40:36          21         0
5       2007-7-8 8:40:36          55         0
6       2007-6-8 8:40:36          3          0
7       2007-5-8 8:40:36          2          0
我写的sql如:
select cid,cdate,cvalue from C 
where ctype=0 and NOT (cvalue = 0 AND TO_CHAR (ADD_MONTHS (SYSDATE + 1,-3),'yyyymmdd') >TO_CHAR (cdate,'yyyymmdd'));写这个例子可能不是很完整,我只是想把NOT改掉,
这样写效率不高,请问这个语句要怎么优化一下呢?

解决方案 »

  1.   

    select   cid,cdate,cvalue   from   C   
    where   ctype=0   and   ((cvalue<>0 AND cdate<trunc(ADD_MONTHS(SYSDATE,-3), 'yyyymmdd ')) or cdate>=trunc(ADD_MONTHS(SYSDATE,-3), 'yyyymmdd ')); 
    我总觉得用ctype来搜索本来效率就不会高 ,因为ctype应该不可能为索引(重复性太高)
      

  2.   

    抱歉,应该如下:
    select   cid,cdate,cvalue   from   C   
    where   ctype=0   and   ((cvalue<>0 AND cdate<trunc(ADD_MONTHS(SYSDATE,-3)) or cdate>=trunc(ADD_MONTHS(SYSDATE,-3))); 
      

  3.   

    三个月前cvalue <> 0,三个月之内的数据cvalue=0,2-11月的数据:select cid,cdate,cvalue   
    from  C  
    where TO_CHAR(ADD_MONTHS(SYSDATE+1,-3), 'yyyymmdd ')< TO_CHAR(cdate, 'yyyymmdd ')
      and (TO_CHAR(ADD_MONTHS(SYSDATE+1,-3), 'yyyymmdd ')>TO_CHAR(cdate, 'yyyymmdd ') and cvalue <> 0)
      and TO_CHAR(cdate, 'yyyymmdd ') between '20070201' and  '20071130'(给楼主提供个思路而已,没有测试)
      

  4.   

    建议不要对date字段做额外的函数处理,如to_char(cdate,)等等,这种会换算表的列值,如果该列有索引,还会使索引失效,这也是我修改成cdate>或者cdate<的理由