我已经在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中的上述更新数据进行排序答案 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
分析函数而不是rank
或dense_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;