请教下,我有一个查询,如下:
select agent_id,sum(t.charge_amt)
  from tdaily_charge t
  where (t.agent_id=i or t.agent_p_id=i or t.agent_pp_id=i)
  and t.dt between
  to_date('2009-4-1','yyyy-mm-dd')
  and to_date('2009-4-30','yyyy-mm-dd')其中i的值在(21,2192,42,146,223,340,3800,439,590,750,1771,2236,1828,1955,2216,2290,2292,2348,2460,2735,2936,3363,3369,3378,4317)这些数字中取,请问如果用PL/SQL写的话,应该如何来写,在线等高手解决!
谢谢!

解决方案 »

  1.   


    能给个例子吗,动态SQL不会啊...
      

  2.   

    select agent_id,sum(t.charge_amt) 
      from tdaily_charge t 
      where (t.agent_id in (...) or t.agent_p_id in (...) or t.agent_pp_id in (...)) 
      and t.dt between 
      to_date('2009-4-1','yyyy-mm-dd') 
      and to_date('2009-4-30','yyyy-mm-dd')
      

  3.   

    也可使用 exists 关键字提高效率
      

  4.   

    declare
      ssql varchar2(200);
    begin
      ssql := 'select * from table '|| 'where id in '|| '(21,2192,42,146,223,340,3800,439,590,750,1771,2236,1828,1955,2216,2290,2292,2348,2460,2735,2936,3363,3369,3378,4317)';
      execute ssql;
    end;
      

  5.   

    是否满足楼主需求:
    CREATE OR REPLACE FUNCTION fnc_charge
    (
    in_agent_id IN NUMBER,
        in_beg_date IN DATE,
        in_end_date IN DATE
    )
    RETURN NUMBER
    IS
    v_sql VARCHAR2(4000);
        n_charge_amt  NUMBER;
    BEGIN
    v_sql := 'select agent_id,sum(t.charge_amt)
                      from tdaily_charge t
                      where (t.agent_id=:i or t.agent_p_id=:i or t.agent_pp_id=:i)
                      and t.dt between to_date('':beg_date'',''yyyy-mm-dd'')
                                           and to_date('':end_date'',''yyyy-mm-dd'')';
         EXECUTE IMMEDIATE v_sql INTO n_charge_amt USING in_agent_id,in_beg_date,in_end_date;
         RETURN n_charge_amt; 
    END;
    /
      

  6.   

    select agent_id,sum(t.charge_amt) 
      from tdaily_charge t 
      where (t.agent_id=i or t.agent_p_id=i or t.agent_pp_id=i) 
      and t.dt between 
      to_date('2009-4-1','yyyy-mm-dd') 
      and to_date('2009-4-30','yyyy-mm-dd')
    group by agent_id这个查询所用到的表结构如下:
    ID          NUMBER(10)                    系统编码       
    DT          DATE                          日期           
    AGENT_ID    NUMBER(10)                    代理商ID       
    CITY_NO     CHAR(5)                       所属城市编码   
    DISTRICT_NO CHAR(3)                       所属地区编码   
    AGENT_P_ID  NUMBER(10)   Y                上级代理商ID   
    AGENT_PP_ID NUMBER(10)   Y                上上级代理商ID 
    CHARGE_QTY  NUMBER(10)   Y                充值笔数       
    CHARGE_AMT  NUMBER(18,2) Y                充值金额因为是要统计大代理的销量(包含下级和下下级),所以在查询语句中使用or条件,4楼的查询方法是不可用的,会把下级的充值量也统计出来。这个查询是应该每次查询后替换i的值进行下一次查询,最后输出每次查询的结果。谢谢各位帮忙!
      

  7.   

    楼主可以我前面提供的函数,或者抽取其中的那段SQL:
    select agent_id,sum(t.charge_amt)
      from tdaily_charge t
      where (t.agent_id=:i or t.agent_p_id=:i or t.agent_pp_id=:i)
      and t.dt between to_date('':beg_date'',''yyyy-mm-dd'')
                           and to_date('':end_date'',''yyyy-mm-dd'')
    group by agent_id 
                                          
    修改如下:
    with id_list as (select column_value id from table(sys.odcivarchar2list(21,2192,42,146,223,340,3800,439,590,750,1771,2236,1828,1955,2216,2290,2292,2348,2460,2735,2936,3363,3369,3378,4317)))
    select agent_id,sum(t.charge_amt)
      from tdaily_charge t1,id_list t2
      where (t1.agent_id=t2.id or t1.agent_p_id=t2.id or t1.agent_pp_id=t2.id)
      and t1.dt between to_date('2009-4-1','yyyy-mm-dd') 
    and to_date('2009-4-30','yyyy-mm-dd')
    group by agent_id
      

  8.   

    select agent_id,sum(t.charge_amt) 
      from tdaily_charge t 
      where (t.agent_id in (21,2192,42,146,223,340,3800,439,590,750,1771,2236,1828,1955,2216,2290,2292,2348,2460,2735,2936,3363,3369,3378,4317)
      and t.dt between 
      to_date('2009-4-1','yyyy-mm-dd') 
      and to_date('2009-4-30','yyyy-mm-dd') 
      

  9.   

    感谢下 beyondme6 ,odcivarchar2list是个好方法,不过要10g以上的版本才能运行,我的数据库版本是9iR2的,用不了,呵呵,我初学PL/SQL,完全是菜鸟中的菜鸟
      

  10.   

    sys.odcivarchar2list只不过是一个type,自己创建一个type:
    CREATE OR REPLACE TYPE my_ODCIVarchar2List AS VARRAY(32767) OF VARCHAR2(4000);
    9i要是不支持with子句的话直接替换掉
    with id_list as (select column_value id from table(my_ODCIVarchar2List(21,2192,42,146,223,340,3800,439,590,750,1771,2236,1828,1955,2216,2290,2292,2348,2460,2735,2936,3363,3369,3378,4317)))
        select agent_id,sum(t.charge_amt)
          from tdaily_charge t1,id_list t2
          where (t1.agent_id=t2.id or t1.agent_p_id=t2.id or t1.agent_pp_id=t2.id)
          and t1.dt between to_date('2009-4-1','yyyy-mm-dd') 
                    and to_date('2009-4-30','yyyy-mm-dd')
        group by agent_id
      

  11.   

    用exist就可以实现了。而且效率还高。