Oracle中的平均查询

时间:2013-12-03 21:22:50

标签: sql oracle

我有一个包含这四个表的数据库:

CREATE TABLE team (  
      id    CHAR(3),  
      name     VARCHAR2(80) CONSTRAINT nn_team_name     NOT NULL,  
      district VARCHAR2(20) CONSTRAINT nn_team_district NOT NULL,  

CONSTRAINT pk_team  
PRIMARY KEY (id)  
);  

 CREATE TABLE game (  
     home,        
     away,  
     round    NUMBER(2) CONSTRAINT nn_game_round NOT NULL,  
     spectators NUMBER(5),  
--  
 CONSTRAINT pk_game  
      PRIMARY KEY (home, away),  
--  
 CONSTRAINT fk_game_home  
      FOREIGN KEY (home)  
      REFERENCES team(id),  
 CONSTRAINT fk_game_away  
      FOREIGN KEY (away)  
      REFERENCES team(id),  
--
 CONSTRAINT ck_game_round  
     CHECK (round BETWEEN 1 AND 30),  
 CONSTRAINT ck_game_spectators
    CHECK (spectators > 0)
);

CREATE TABLE player (  
     nickname        NUMBER(8),  
     name       VARCHAR2(80) CONSTRAINT nn_player_name      NOT NULL,  
     yearOfBirth NUMBER(4)    CONSTRAINT nn_player_yearOfBirth NOT NULL,   
     team                  CONSTRAINT nn_player_team    NOT NULL,  
--
CONSTRAINT pk_player  
    PRIMARY KEY (nickname),  
--
CONSTRAINT fk_player_team  
    FOREIGN KEY (team)  
    REFERENCES team(id),  
--
CONSTRAINT ck_player_yearOfBirth  
    CHECK (yearOfBirth BETWEEN 1950 AND 2000)  
);

CREATE TABLE plays (  
    player,  
    home,         
    away,    
    goals      NUMBER(2) CONSTRAINT nn_plays_goals NOT NULL,  
--
CONSTRAINT pk_plays  
    PRIMARY KEY (player, home, away),  
--
CONSTRAINT fk_plays_player  
     FOREIGN KEY (player) REFERENCES player(nickname),  
CONSTRAINT fk_plays_game  
     FOREIGN KEY (home, away) REFERENCES game(home, away),  
--
CONSTRAINT ck_plays_goals   
     CHECK (goals >= 0)  

);

我在这四个问题上遇到了麻烦:

  • 每轮每场比赛的平均进球数。结果应按整数排序。
  • 玩家的名字和昵称,以及他们在不到五场比赛中出场的球队身份。结果应该包括没有在任何游戏中玩过的玩家。必须只有一个SELECT子句。
  • 每轮进球数较多的球队的身份证明。如果有多个球队的目标数量较多,则两支球队都应在结果中显示。假设球队每轮都参加比赛。
  • Nicknames和他们俱乐部的身份,对于那些在两场比赛中得分更多的球员,只有两场比赛。如果在这种情况下有多个玩家,则不会显示任何玩家。
你可以帮帮我吗?因为我设法做了更简单的查询,但我陷入了困境......

1 个答案:

答案 0 :(得分:0)

未经测试,因为我没有任何测试数据......

查询1

--    Average number of goals per game per round.
--    The result should be ordered by round number.
WITH num_games AS (
  SELECT COUNT(1) AS num_games,
         round
  FROM   game
  GROUP BY round
)
SELECT g.round,
       SUM( p.goals / n.num_games )
         AS avg_goals_per_game_per_round
FROM   game g
       INNER JOIN
       plays p
       ON ( g.home = p.home AND g.away = p.away )
       INNER JOIN
       num_games n
       ON ( g.round = n.round )
GROUP BY g.round
ORDER BY g.round;

查询2

--    Names and nicknames of the players, and their team id's,
--    that played away in less than five games.
--    The result should include the players that didn't played in any game.
--    There must be ONLY one SELECT clause.
SELECT p.nickname,
       p.name,
       p.team
FROM   player p
       LEFT OUTER JOIN
       plays l
       ON ( p.nickname = l.player )
GROUP BY p.nickname, p.name, p.team
HAVING COUNT( 1 ) < 5;

查询3

--    id's of the teams with the larger number of goals against per round.
--    In case there's more than one team with the larger number
--    of goals against, both teams should show in the result.
--    Assume the teams play in every round.
WITH player_home_or_away_goals AS (
  SELECT player,
         home,
         away,
         goals,
         CASE WHEN home = (SELECT team
                           FROM   player p
                           WHERE  p.nickname = l.player)
              THEN 'H'
              ELSE 'A'
              END AS home_away
  FROM   plays l
),
game_home_or_away_goals AS (
  SELECT home,
         away,
         SUM( DECODE( home_away, 'H', goals, null ) ) AS home_goals,
         SUM( DECODE( home_away, 'A', goals, null ) ) AS away_goals
  FROM   player_home_or_away_goals
  GROUP BY home, away
),
team_goals_per_game_per_round AS (
  SELECT g.home AS team_id,
         h.home_goals AS goals_for,
         h.away_goals AS goals_against,
         g.round
  FROM   game g
         INNER JOIN
         game_home_or_away_goals h
         ON ( g.home = h.home AND g.away = h.away )
  UNION ALL
  SELECT g.away AS team_id,
         h.away_goals AS goals_for,
         h.home_goals AS goals_against,
         g.round
  FROM   game g
         INNER JOIN
         game_home_or_away_goals h
         ON ( g.home = h.home AND g.away = h.away )
),
total_team_goals_per_round AS (
  SELECT team_id,
         round,
         SUM( goals_for )     AS total_goals_for_per_round,
         SUM( goals_against ) AS total_goals_against_per_round
  FROM   team_goals_per_game_per_round
  GROUP BY team_id,
           round
),
max_goals_against_per_round AS (
  SELECT round,
         MAX( total_goals_against_per_round ) AS greatest_goals_against
  FROM   total_team_goals_per_round
  GROUP BY round
)
SELECT t.team_id,
       t.round
FROM   total_team_goals_per_round t
       INNER JOIN
       max_goals_against_per_round m
       ON (    t.round = m.round
           AND t.total_goals_against_per_round = m.greatest_goals_against );

查询4

--    Nicknames and id's of their clubs, for the players that scored
--    the larger number of goals in two, and only two games. If there
--    are more than one player in this conditions, none is shown.

请发布一些测试数据和所需的输出,因为不清楚该问题的具体要求是什么。

  • 你想要那些只玩过两场比赛然后从那个子集中找到得分最高的球员的球员子集吗?
  • 或者,您是否希望在两场比赛中得分最高的球员,无论他们总共玩过多少场比赛?
  • 或者,这是别的吗?