Oracle存储过程 - 渐变变量的建立

时间:2014-05-22 17:50:58

标签: oracle stored-procedures out-parameters

对不起我的奇怪称号,但我不知道我究竟想要什么。任务很简单。我有比赛表。另一个表组。每个小组都有几位参赛者。在最后一个表中存储了参赛者的结果。任务是获得每个小组的前三名参赛者。

所以我必须遍历小组,获得每个小组的前三名参赛者(根据获得的分数)并将它们添加到一些变量中。

这是伪代码:

CREATE OR REPLACE PROCEDURE get_first_three_of_all(contestants OUT SOME_TYPE) AS
    CURSOR groups SELECT...
BEGIN
    FOR group IN groups LOOP
        APPEND(contestants, get_first_three_of_one_group(group.id))
    END LOOP;
END;

我不知道,如何解决这个任务。我甚至不知道我应该寻找什么。你会这么善良并帮助我吗?感谢。

编辑:我的表格的简化结构:

  1. 比赛:competition_id
  2. 参赛者:contestant_id
  3. GroupContestant:contestant_group_id,competition_d,group_number,contestant_id
  4. 结果:contestant_group_id,juror,points
  5. 选择以获取一个组的数据(组号YYY)在此处:

    SELECT * FROM (
          SELECT res.contestant_group_id, SUM(res.points) AS points
            FROM Result res
           WHERE res.couple_group_id IN (SELECT couple_group_id
                                           FROM GroupContestant
                                          WHERE competition_id = XXX
                                            AND group_number = YYY)
        GROUP BY res.contestant_group_id
        ORDER BY points DESC
    )
     WHERE ROWNUM <= 3;
    

2 个答案:

答案 0 :(得分:1)

Analytic functions救援。要为每个组选择前3个结果,每个比赛:

SELECT * FROM (
    SELECT grp.competition_id, grp.group_number, res.contestant_group_id, res.points,
           row_number() over (partition by grp.competition_id, grp.group_number
                                   order by res.points desc) rn
      FROM (SELECT contestant_group_id, SUM(points) AS points
              FROM Result
             GROUP BY contestant_group_id) res
      JOIN GroupContestant grp ON (grp.contestant_group_id = res.contestant_group_id)
 )
 WHERE rn <= 3;

注意你如何解决关系(考虑使用rankdense_rank代替row_number)。

答案 1 :(得分:1)

您可以使用RANK()分析函数来实现目标:

select *
  from (select group_num,
               points,
               rank() over(partition by group_num order by points desc) rank
          from results
         inner join group_contestant
         using (contestant_group_id))
 where rank <= 3
 order by group_num, points desc;

以下是SQLFiddle