看了樓主的代碼,好象都是用SQL SERVER的思維來在ORACLE上做事,這太不好了,其實上面語句可以使用ORACLE的函數讓它寫得很簡單的,而且效率高。
今天沒時間寫了,下周一幫你寫。

解决方案 »

  1.   

    你可以试着使用下优化策略:在每一个Select后(包括视图)加上/*+Rule*/看看呢
    另外需要注意的就是在对主表进行数据关联的时候尽量避免全表扫描,适当使用优化策略
    能不使用视图尽量不要使用视图,如果记录数太大的话视图的效率是非常低下的,可以考虑使用临时表
      

  2.   

    不知道您的业务情况,通过语句了解一些。
    首先,第一个语句不需要与ws_planinfo表连接,若ws_send存在ws_planinfo不存在的plan_code就另说了。优化如下:
    select  ws_planinfo.plan_code,ws_planinfo.plan_numbers,a.send_flow,    
    decode(sign(a.num-ws_planinfo.plan_numbers),1,ws_planinfo.plan_numbers,a.num) num
          from ws_planinfo,
          (select plan_code,ws_send.send_flow,sum(ws_send.send_num) as num 
           from  ws_send
       group by plan_code,send_flow)a
       where ws_planinfo.plan_code=a.plan_code 第一个语句一样,不要与ws_planinfo连接,
    最后一个没有完全看明白,不过明显是一个错误的SQL,而且刊需要应该是两个SQL,而不是一个。
      

  3.   

    認真看了樓主的代碼,基本上明白了樓主的意思,建議樓主使用Oracle的思維來寫SQL語句,不應該用SQL SERVER的思維來寫SQL語句(我猜測樓主可能是用SQL SERVER的思維寫的,呵呵!),使用Oracle中的函數來達到樓主的要求是相當簡便的,我給的參考代碼如下:
    WITH q_View AS (
    SELECT 
    t1.plan_code,max(t1.plan_numbers) plan_numbers,t2.send_flow,
    max(t2.send_num) send_num,count(t3.repair_id) blooey_num--不能使用Count(t3.*) 
    FROM  
    ws_planinfo t1 JOIN ws_send t2 ON t1.plan_code=t2.plan_code 
    LEFT JOIN WS_REPAIR t3 ON t2.plan_code=t3.change_num and t2.send_flow=t3.send_flow
    GROUP by t1.plan_code,t2.send_flow)
    SELECT  
        PLAN_CODE,MAX(PLAN_NUMBERS) PLAN_NUMBERS,
        SEND_FLOW,decode(SIGN(max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),Max(send_num)) NUM, --各工序實際生產數
        max(blooey_num) BLOOEY_NUM ,--各工序故障数量
        max(blooey_num)/decode(SIGN(max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),Max(send_num)) as flow_blooey_percent,--工序故障率
       (sum(blooey_num) over(partion by plan_code))/MAX(PLAN_NUMBERS) as blooey_percent--批次故障率
    FROM 
    q_View
    GROUP BY PLAN_CODE,SEND_FLOW;以上語句,樓主可以直接拷入你的SQL*Plus中進行測試(或許因為沒有正確理解樓主的意思,我的語句可能會有錯),因為不知道你的Oracle的版本,所以沒有使用MODEl函數,如果使用MODEL函數,可能還更簡單些。
      

  4.   

    不好意思,經過我的檢查,我的語句有點小錯誤,正確的應該如下:
    WITH q_View AS (
    SELECT 
    t1.plan_code,max(t1.plan_numbers) plan_numbers,t2.send_flow,
    max(t2.send_num) send_num,count(t3.repair_id) blooey_num
    FROM  
    ws_planinfo t1 JOIN ws_send t2 ON t1.plan_code=t2.plan_code 
    LEFT JOIN WS_REPAIR t3 ON t2.plan_code=t3.change_num and t2.send_flow=t3.send_flow
    GROUP by t1.plan_code,t2.send_flow)
    SELECT  
        PLAN_CODE,MAX(PLAN_NUMBERS) PLAN_NUMBERS,
        SEND_FLOW,decode(SIGN(max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),Max(send_num)) NUM, --各工序實際生產數
        max(blooey_num) BLOOEY_NUM ,--各工序故障数量
        max(blooey_num)/decode(SIGN(max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),Max(send_num)) as flow_blooey_percent,--工序故障率
       (sum(max(blooey_num)) over (partion by plan_code))/MAX(PLAN_NUMBERS) as blooey_percent--批次故障率
    FROM 
    q_View
    GROUP BY PLAN_CODE,SEND_FLOW;上面語句已經過我的測試,能返回正確的結果,樓主可以使用一些典型數據進行測試。
      

  5.   

    oracle 8.1.7
    你的语句好象有问题,另外
    SELECT 
    t1.plan_code,max(t1.plan_numbers) plan_numbers,t2.send_flow,
    max(t2.send_num) send_num,count(t3.repair_id) blooey_num
    FROM  
    ws_planinfo t1 JOIN ws_send t2 ON t1.plan_code=t2.plan_code 
    LEFT JOIN WS_REPAIR t3 ON t2.plan_code=t3.change_num and t2.send_flow=t3.send_flow
    GROUP by t1.plan_code,t2.send_flow这里好象也不符合要求啊,每个批次的数量求最大值没有意义,
    当生产数量大于计划数量时,按计划数量为准(因存在返工,故生产数量有可能大于计划数量)
    每个工序有可能传送多次,每个工序实际的生产数量也可能不同,
    前工序生产,后工序可能还没有生产,这里的各工序是完成生产同一件产品的不同功能部分
    所以要sum(send_num),不能max(send_num)
      

  6.   

    ws_planinfo t1 JOIN ws_send t2 ON t1.plan_code=t2.plan_code 
    LEFT JOIN WS_REPAIR t3 ON t2.plan_code=t3.change_num and t2.send_flow=t3.send_flow
    GROUP by t1.plan_code,t2.send_flow
    另外你这里的join也有问题
      

  7.   

    那稍微改一下就可以了:
    WITH q_View AS (
    SELECT 
    t1.plan_code,max(t1.plan_numbers) plan_numbers,t2.send_flow,
    SUM(t2.send_num) send_num,count(t3.repair_id) blooey_num
    FROM  
    ws_planinfo t1 JOIN ws_send t2 ON t1.plan_code=t2.plan_code 
    LEFT JOIN WS_REPAIR t3 ON t2.plan_code=t3.change_num and t2.send_flow=t3.send_flow
    GROUP by t1.plan_code,t2.send_flow)
    SELECT  
        PLAN_CODE,MAX(PLAN_NUMBERS) PLAN_NUMBERS,
        SEND_FLOW,decode(SIGN(Max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),max(send_num)) NUM, --各工序實際生產數
        max(blooey_num) BLOOEY_NUM ,--各工序故障数量
        max(blooey_num)/decode(SIGN(max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),max(send_num)) as flow_blooey_percent,--工序故障率
       (sum(max(blooey_num)) over (partion by plan_code))/MAX(PLAN_NUMBERS) as blooey_percent--批次故障率
    FROM 
    q_View
    GROUP BY PLAN_CODE,SEND_FLOW;至於你說的 join 處有問題,你能否說清楚些?我在SQL*Plus中測試過,應該沒問題!
      

  8.   

    哦,明白了,樓主的Oracle版本還是Oracle 8.1.7的(我的測試環境是Oracle 10g的),那就無法使用JOIN運算子也無法使用LEFT JOIN(如果使用,肯定會出語法錯誤),對於內連接和外連接隻能放在Where子句中,另外對於Oracle 8.1.7的是否能使用分析函數和能否使用重用查詢我也不能肯定,如果不能使用的話,那我給的語句將無法使用,我現在改成能在Oracle8.1.7中運行的語句(假設Oracle8.1.7能使用分析函數和能重用查詢),樓主可以再試試看:
    WITH q_View AS (
    SELECT 
    t1.plan_code,max(t1.plan_numbers) plan_numbers,t2.send_flow,
    SUM(t2.send_num) send_num,count(t3.repair_id) blooey_num
    FROM  
    ws_planinfo t1 ,ws_send t2,WS_REPAIR t3 
    Where t1.plan_code=t2.plan_code And t2.plan_code+=t3.change_num and t2.send_flow+=t3.send_flow
    GROUP by t1.plan_code,t2.send_flow)
    SELECT  
        PLAN_CODE,MAX(PLAN_NUMBERS) PLAN_NUMBERS,
        SEND_FLOW,decode(SIGN(Max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),max(send_num)) NUM, --各工序實際生產數
        max(blooey_num) BLOOEY_NUM ,--各工序故障数量
        max(blooey_num)/decode(SIGN(max(send_num)-MAX(PLAN_NUMBERS)),1,
                MAX(PLAN_NUMBERS),max(send_num)) as flow_blooey_percent,--工序故障率
       (sum(max(blooey_num)) over (partion by plan_code))/MAX(PLAN_NUMBERS) as blooey_percent--批次故障率
    FROM 
    q_View
    GROUP BY PLAN_CODE,SEND_FLOW;如果Oracle8.1.7不能使用重用查詢,樓主可以將WITH後的語句先做成一個視圖,再運行後面的SELECT語句,如果不用使用分析函數,那就沒辦法了!!沉得樓主的Oracle版本太低了,至少應該升到Oracle9i
      

  9.   

    oracle8.1.7的函数好象不支持with吧!
      

  10.   

    我說了,要是不支持WITH的話,那先做成一個視圖,再使用後面的SELECT語句!
      

  11.   

    但是你的语句算法也不对,你用了太多的max函数,但是这样算的结果是错误的,你可以自己插入数据试一下。
    over (partion by plan_code) 这里也没看懂
      

  12.   

    我已經測試過,樓主可以自已試試,我用MAX函數是因為某些列已經在WITH語句中用聚合函數計算過了,所以必須得用MAX,
    over (partion by plan_code) 是分析函數的用法。另外,如果樓主的Oracle為10g的話,那可以使用模型函數,我的語句還可以大大簡化。
      

  13.   

    over (partion by plan_code) 是分析函數的用法
    这里写错拉,应该如下:
    over (partition by a.plan_code)另外
    SELECT 
    t1.plan_code,max(t1.plan_numbers) plan_numbers,t2.send_flow,
    SUM(t2.send_num) send_num,count(t3.repair_id) blooey_num
    FROM  
    ws_planinfo t1 ,ws_send t2,WS_REPAIR t3 
    Where t1.plan_code=t2.plan_code And t2.plan_code+=t3.change_num and t2.send_flow+=t3.send_flow
    GROUP by t1.plan_code,t2.send_flow这里统计的故障数目不对,
    因为同一批次同一工序可以有多次传送生产的产品记录,这样一块故障表就会被重复统计。
      

  14.   

    1. 工作令表  ws_planinfo
       批次        计划生产数量     状态
       plan_code    plan_numbers    status(1表示未完工,2表示完工)2.物料传送记录表 ws_send
      批次          工序        数量         状态
      plan_code     send_flow   send_num     status(1传送,2接收,3入库)
    3.故障记录表
     批次           送修工序     维修ID       类型
    change_num       give_proc    repair_id   code_type(0表示新投,1表示改制)
    各工序故障表数量
    create or replace view view_flow_blooey_num_plan as
    (select WS_REPAIR.CHANGE_NUM AS PLAN_CODE,WS_REPAIR.GIVE_PROC as give_proc,
       COUNT(WS_REPAIR.REPAIR_ID) AS blooey_num
       from WS_REPAIR,WS_PLANINFO
       where WS_REPAIR.CHANGE_NUM=WS_PLANINFO.PLAN_CODE  and
             WS_REPAIR.CODE_TYPE=0 and WS_PLANINFO.status='1'   
       group by WS_REPAIR.CHANGE_NUM,WS_REPAIR.GIVE_PROC)
    各工序传送数量
    CREATE OR REPLACE VIEW SEND_FLOW_COUNT AS
    SELECT 
    t1.plan_code,max(t1.plan_numbers) plan_numbers,t2.send_flow,
    SUM(t2.send_num) send_num
    FROM  
    ws_planinfo t1 ,ws_send t2
    Where  t1.plan_code=t2.plan_code and
     t2.status >='2' 
     and t1.status='1'
    GROUP by t1.plan_code,t2.send_flow
    求工序未生产完工批次故障率
    SELECT  
        a.PLAN_CODE,MAX(a.PLAN_NUMBERS) PLAN_NUMBERS,
        a.SEND_FLOW,decode(SIGN(Max(a.send_num)-MAX(a.PLAN_NUMBERS)),1,
                MAX(a.PLAN_NUMBERS),max(a.send_num)) NUM, --各工序实际生产数量,当传送数量大于计划数                                --量时,按计划数量为准(因存在返工,故传送数量有可能大于计划数量)
        max(b.blooey_num) BLOOEY_NUM ,--各工序故障数量
        max(b.blooey_num)/decode(SIGN(Max(a.send_num)-MAX(a.PLAN_NUMBERS)),1,
                MAX(a.PLAN_NUMBERS),max(a.send_num)) as flow_blooey_percent,--工序故障率
       (sum(max(b.blooey_num)) over (partition by a.plan_code))/MAX(a.PLAN_NUMBERS) as blooey_percent--批次故障率
    FROM send_flow_count a,view_flow_blooey_num_plan b
    where a.send_flow=b.give_proc and
          a.plan_code=b.plan_code
    GROUP BY a.PLAN_CODE,a.SEND_FLOW;
    上面是我目前采用的办法