如何使用pl sql块对表中的数据进行排序

时间:2015-11-20 10:33:51

标签: sql database oracle plsql

我已经在top_books的rank_id列中给出了排名,我想根据count_issue属性更新同一个表,同时保持rank_id不变。这可以以某种方式完成吗?

DECLARE
  v_row NUMBER;
  CURSOR cur IS
    SELECT COUNT(transaction_id) counter, book_id 
    FROM transaction_master 
    GROUP BY book_id;
BEGIN
  FOR rec IN cur LOOP
    v_row:=cur%ROWCOUNT;
    UPDATE top_books 
    SET book_id = rec.book_id, count_issue = rec.counter 
    WHERE rank_id = v_row;
  END LOOP;
END;

如何根据'COUNT_ISSUE'属性

对此代码块中的表top_books中的上述更新数据进行排序

4 个答案:

答案 0 :(得分:2)

我不会使用游标for循环来执行此操作;相反,我会在单个MERGE语句中执行此操作:

merge into top_books tgt
using (select row_number() over (order by cnt desc, book_id) rn,
              book_id,
              cnt
       from   (select   book_id,
                        count(transaction_id) cnt
               from     transaction_master
               group by book_id)) src
  on (tgt.rank_id = src.rn)
when matched then
  update set tgt.book_id = src.book_id,
             tgt.count_issue = src.cnt;

它会比你的逐行(又名慢慢)方法快得多。

N.B。我使用row_number分析函数而不是rankdense_rank来确定销售书籍的顺序,因为如果两本书碰巧具有相同的计数,则更新将失败。你应该修改额外的顺序(这里,我使用book_id来区分哪本书会先出版)以达到你想要的结果。

答案 1 :(得分:1)

数据未在top_books表中自行排序。这将违反SQL范式。您在查询表时对数据进行排序,例如:

SELECT book_id, count_issue
FROM top_books
ORDER BY count_issue DESC

如果要在PL / SQL中使用它,可以使用此查询定义一个游标,它将按排序顺序一次一个地为您提供记录。

答案 2 :(得分:1)

试试这个你也可以进行更新,但是只是改变光标就会让人感到困惑;

DECLARE
  v_row NUMBER;
 CURSOR cur IS
    select * from (SELECT COUNT(transaction_id) counter, book_id 
    FROM transaction_master 
    GROUP BY book_id) order by counter desc;

BEGIN
  -- truncate table
  execute immediate 'truncate table top_books';
  --insert fresh data
  FOR rec IN cur LOOP
    v_row := cur%rowcount;
   insert into top_books (rank_id,book_id,ciybt_issue) values(v_row,rec.book_id,rec.counter);
  END LOOP;
  commit;
END;

答案 3 :(得分:-1)

谢谢大家的帮助, 我通过将光标更改为

找到了答案
CURSOR cur IS
SELECT COUNT(transaction_id) counter, book_id 
FROM transaction_master 
GROUP BY book_id ORDER BY counter desc;