2017-04-09 70 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)的索引。
  • 订单没有重复项目。
  • 最大的订单数量有限(比如几十个)。