如何在循环中用光标找到MAX

时间:2017-10-08 23:14:48

标签: plsql

我需要找到拥有最多受欢迎视频的帐户,但我不知道如何增加帐户ID以循环访问所有帐户。

我知道如何查找每个帐户的优惠视频数量。

DECLARE 
    userid  NUMBER(3) := 2; 
    CURSOR items IS 
      SELECT id_account 
      FROM   favorites; 
    counter NUMBER(3) := 0; 
BEGIN 
    FOR x IN items LOOP 
        IF x.id_account = userid THEN 
          counter := counter + 1; 
        END IF; 
    END LOOP; 

    dbms_output.Put_line(counter); 
END; 

Edit1 :感谢您的回复,但我忘了提到我必须使用光标作为练习目标

这是我的收藏夹(id_account [PK,FK],id_video [PK,FK])

Edit2 :谢谢,这正是我想要的

1 个答案:

答案 0 :(得分:0)

当简单的SQL可以为您执行此操作时,没有理由使用PL / SQL复杂化。

例如,此查询会根据喜欢的视频数量(从最大数量到最低数量)为您提供帐户ID和最喜欢的视频数量:

select id_account, count(*)
  from favorites
 group by id_account
 order by 2 desc;

现在你需要决定如果多个帐户拥有相同数量的收藏视频该怎么办 - 你会全部展示,还是只展示一个(随机)?

以下查询将只返回一个帐户:

select *
  from (select id_account, count(*) num_fav_videos
          from favorites
         group by id_account
         order by 2 desc)
 where rownum = 1;

请注意,这些查询效率不高 - 他们必须汇总每个帐户ID的数据,而不是排序数据。

[编辑]由于要求使用游标(我不同意该要求!),您可以使用一个游标进行循环,并将中间数据存储在单独的变量中。

在下面的示例中,我将计数器和最大计数设置为0,然后浏览存储在链接帐户和收藏视频的表格中的所有帐户。我存储该帐户的当前帐户ID和增加的视频数,直到光标中的帐户更改或我到达最后一行。然后,我将该帐户的收藏视频数量与当前最大视频数量进行比较,如果更高,我会存储新的最大视频数量和帐户ID。

declare
  cursor items is
    select id_account
      from favorites
     order by id_account;

  id_account_curr number;
  id_account_max  number;
  max_count number;
  counter number;
begin
  counter := 0;
  max_count := 0;
  for x in items loop
    if x.id_account = id_account_curr then -- while account is the same increment number of favorite videos
      counter := counter + 1;
    else
      if counter > max_count then
        max_count := counter;
        id_account_max := id_account_curr;
      end if;
      id_account_curr := x.id_account; -- change current account id
      counter := 1; -- practice question: why is counter set to 1 and not 0?
    end if;
  end loop;
  if counter > max_count then -- practice question: what is this for?
    max_count := counter;
    id_account_max := id_account_curr;
  end if;
  dbms_output.put_line('id_account: ' || to_char(id_account_max) || ', count: ' || to_char(max_count));
end;