2

ポイント、ゴール差、各チームの得点を含む順位表と呼ばれるテーブルがあります。これがテーブル構造とデータです。

CREATE TABLE standings (
  team_id int(3) unsigned NOT NULL AUTO_INCREMENT,
  points int(2) unsigned DEFAULT 0,
  goal_difference int(2) unsigned DEFAULT 0,
  goals_for int(2) unsigned DEFAULT 0,
  PRIMARY KEY (team_id)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;

insert into standings(team_id,points,goal_difference,goals_for) values (1,20,2,17);
insert into standings(team_id,points,goal_difference,goals_for) values (2,14,8,15);
insert into standings(team_id,points,goal_difference,goals_for) values (3,9,2,11);
insert into standings(team_id,points,goal_difference,goals_for) values (4,14,10,12);
insert into standings(team_id,points,goal_difference,goals_for) values (5,17,10,19);
insert into standings(team_id,points,goal_difference,goals_for) values (6,5,-11,7);
insert into standings(team_id,points,goal_difference,goals_for) values (7,14,10,10);
insert into standings(team_id,points,goal_difference,goals_for) values (8,9,2,14);
insert into standings(team_id,points,goal_difference,goals_for) values (9,12,1,10);
insert into standings(team_id,points,goal_difference,goals_for) values (10,9,2,14);
commit;

このテーブルをポイント、goal_difference、goals_for の降順に並べ替え、この順序に基づいて各チームにランクを割り当てたいと思います。mySQL には RANK 関数がないため、このサイトを検索した後、このクエリを思いつきました。

SELECT CASE
          WHEN @prev_value = concat(points,'-',goal_difference,'-',goals_for)
          THEN
             @cur_rank
          WHEN @prev_value := concat(points,'-',goal_difference,'-',goals_for)
          THEN
             @cur_rank := @cur_rank + 1
       END
          AS rank, s.team_id, s.points, s.goal_difference, s.goals_for
  FROM standings s, (SELECT @cur_rank := 0) p, (SELECT @prev_rank := 0) q, (SELECT     @prev_value := NULL) r
 ORDER BY s.points DESC, s.goal_difference DESC, s.goals_for DESC;

ここまでは順調ですね。今、私は2つの質問があります。

  1. 上記のクエリの結果を見ると、チーム 8 とチーム 10 が同点で 7 位です。そこで、ランク 9 を次のチーム 3 に割り当てたいと思います。クエリに列を追加せずにこれを行うにはどうすればよいでしょうか。
  2. このクエリを使用して VIEW を作成したいと考えています。しかし、mySQL では作成できず、「ビューの SELECT に変数またはパラメータが含まれています」というエラーが表示されます。このためにVIEWを作成する方法を提案してください。

    CREATE VIEW view_standings
    AS
       SELECT CASE
         WHEN @prev_value = concat(points,'-',goal_difference,'-',goals_for)
         THEN
            @cur_rank
         WHEN @prev_value := concat(points,'-',goal_difference,'-',goals_for)
         THEN
            @cur_rank := @cur_rank + 1
      END
         AS rank,s.team_id,s.points,s.goal_difference,s.goals_for
    FROM standings s,(SELECT @cur_rank := 0) p,(SELECT @prev_rank := 0) q,(SELECT @prev_value := NULL) r
    ORDER BY s.points DESC, s.goal_difference DESC, s.goals_for DESC;
    
4

1 に答える 1

2

相関サブクエリを使用してランキングを行うこともできます。適度な量のデータがある場合でも、これは計算集約型であることが判明する可能性があります。

 select s.*,
        (select 1+COUNT(*)
         from standings s2
         where s2.points > s.points or
               (s2.points = s.points and s2.goal_difference > s.goal_difference) or
               (s2.points = s.points and s2.goal_difference = s.goal_difference and s2.goals_for > sys.goals_for
        ) as ranking
 from standings s

句にサブクエリしかないため、fromこれをビューとして使用できます。

インデックスを no にすることでパフォーマンスを向上できると思いますstandings(points, goal_difference, goals_for)

于 2013-04-29T13:46:09.260 に答える