2014-09-25 140 views
0

我有兩個表tab1和tab2,每個表都有兩列acc_num和prod_code。我需要從tab1更新tab2中的prod_code。以下是兩個表中的示例數據:查詢性能問題

TAB1 

acnum  Prod 
------------------- 
1   A 
2   B 
2   C 
3   X 
3   X 

Tab2 

acnum  Prod 
------------------- 
1   null 
2   null 
2   null 
3   null 
3   null 

對於更新後的第二張表,應該連接所有不同的代碼。以下是示例輸出。

Tab2 

acnum  Prod 
------------------- 
1   A 
2   B|C 
2   B|C 
3   X 
3   X 

我能夠通過PL/SQL來實現這一點,但它採取的年齡來完成。 (實際表格有數百萬條記錄)。以下是我正在使用的代碼。

DECLARE 
    l_acnum dbms_sql.varchar2a; 
    l_prod dbms_sql.varchar2a; 
    l_prod2 VARCHAR2(10):= NULL; 
    l_count NUMBER  := 0; 
    CURSOR cr_acnum 
    IS 
    SELECT DISTINCT(acnum) FROM tab1; 
    CURSOR cr_prod(l_acnum_dum IN VARCHAR2) 
    IS 
    SELECT prod FROM tab1 WHERE acnum = l_acnum_dum; 
BEGIN 
    OPEN cr_acnum; 
    FETCH cr_acnum bulk collect INTO l_acnum; 
    CLOSE cr_acnum; 
    FOR i IN l_acnum.first .. l_acnum.last 
    LOOP 
    OPEN cr_prod(l_acnum(i)); 
    FETCH cr_prod bulk collect INTO l_prod; 
    CLOSE cr_prod; 
    FOR m IN l_prod.first .. l_prod.last 
    LOOP 
     IF m   <> 1 THEN 
     IF l_prod(m) = l_prod(m-1) THEN 
      l_prod2 := l_prod(m); 
     ELSE 
      l_prod2 := l_prod2||'|'||l_prod(m); 
     END IF; 
     ELSE 
     l_prod2 := l_prod(m); 
     END IF; 
    END LOOP; 
    UPDATE tab2 SET prod = l_prod2 WHERE acnum = l_acnum(i); 
    END LOOP; 
END; 

這個pl/sql塊需要很長時間才能完成。無論如何,我可以通過查詢而不是PL/SQL來實現,也可以通過高效的PL/SQL來實現。我也嘗試過BULK COLLECT,但沒用。數據在Oracle數據庫中。非常感謝您的時間。

+1

它必須在plsql中或可以sql? – Aramillo 2014-09-25 16:46:43

回答

0

謝謝大家對您的輸入。我使用你的輸入實現了同樣的功能。我使用了2步解決方案:

步驟1)爲產品和帳戶號創建查找表。

create table lkup_tbl 
as SELECT acnum, LISTAGG(Prod, '|') WITHIN GROUP (ORDER BY Prod) product 
FROM (select distinct acnum, Prod from tab1) tab 
GROUP BY acnum; 

步驟2)現在通過加入這個查找表來更新所有的表格。

update tab2 t1 
set (t1.Prod) = (select product from lkup_tbl t2 
where t2.acnum = t1.acnum 
); 
1

只要這些值不超過一定的總長度,就會連接這些值。如果存在任何欺騙,你可能還想做一個子查詢去重複它們。

更新:這裏是LISTAGG

update table2 set Prod = (
SELECT LISTAGG(t1.Prod, ', ') WITHIN GROUP (ORDER BY t1.Prod) "Prod" 
    FROM Table1 t1 
where t1.acnum = table2.acnum) 
+1

根據Oracle,wm_concat是不受支持的函數。也許用listagg代替? – OldProgrammer 2014-09-25 16:01:12

+0

listagg會工作 - 舊版本沒有它,雖然 – jle 2014-09-25 16:02:07

+0

oops,你是對的。 OP沒有指定版本。 – OldProgrammer 2014-09-25 16:02:42