2017-04-09 96 views
0

我與列甲骨文 - 排序表中基於列

ORD_ID, AI_LN, ITEM 

的數據是一樣

A100 null 0
A100 null 108632 
A100 null 501632 
A200 null 301632 
A200 null 601732 

我需要根據順序進行編號AI_LN表CUSTOMER_ORDER,所以它變成

A100 0 0
A100 1 108632 
A100 2 501632 
A200 0 301632 
A200 1 601732 

如何做到這一點?它會通過PLSQL塊嗎?

回答

0

沒有必要使用PL/SQL,這可以在SQL中使用ROW_NUMBER解析函數來完成:

SELECT ORD_ID, 
     ROW_NUMBER() OVER (PARTITION BY ORD_ID 
          ORDER BY ITEM) -- or ORDER BY ROWNUM 
     AS ai_ln, 
     ITEM 
FROM customer_order; 

如果要更新,則表:

UPDATE customer_table c 
SET ai_ln = (
    SELECT rn 
    FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY ord_id 
           ORDER BY item) 
      AS rn 
    FROM customer_table 
) r 
    WHERE c.ROWID = r.ROWID 
); 

或者MERGE

MERGE INTO customer_table dst 
USING (SELECT ROW_NUMBER() OVER (PARTITION BY ord_id 
            ORDER BY item) AS rn 
     FROM customer_table) src 
ON (dst.ROWID = src.ROWID) 
WHEN MATCHED THEN 
    UPDATE SET ai_ln = src.rn; 
+0

糾正我,如果我錯了,但更新與自相關查詢表,這是一個昂貴的,不是嗎?我認爲這將循環更有效率。 – Seyran

+0

@Seyran如果你正在談論一個PL/SQL循環,那麼上下文切換將更加快速。 – MT0

0

使用row_number()解析函數:

select ORD_ID 
    , row_number() over(partition by ORD_ID order by ITEM) -1 as AI_LN 
    , ITEM 
    from table; 
2

如果你只是想選擇ai_ln給出,你可以在選擇使用的窗函數:

select ord_id, 
    row_number() over (
     partition by ord_id order by item 
     ) - 1 as ai_ln, 
    item 
from your_table; 

如果你想用它來更新表,可以在合併使用聲明。

merge into your_table t 
using (
    select ord_id, 
     row_number() over (
      partition by ord_id order by item 
      ) - 1 as ai_ln, 
     item 
    from your_table 
    ) s 
    on (s.rowid = t.rowid) 
when matched 
    then 
     update 
     set t.ai_ln = s.ai_ln; 
0

你可以做到這一點沒有row_number()

update t 
    set ai_ln = (select count(*) from t t2 where t2.ord_id = t.ord_id and t2.item <= t.item); 

你會想用這個在下列情況下:

  • 您對(ord_id, item)的索引。
  • 訂單沒有重複項目。
  • 最大的訂單數量有限(比如幾十個)。