对于此数据库:
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 DISTINCT P1.Name, T.Name
FROM Player P1, Plays P2, Team T, Game G
WHERE P1.team = T.id
AND P1.nickname = P2.player
AND P1.team = G.away
AND P1.team = P2.away;
这是我的尝试:
WITH Number_of_Games AS (
SELECT COUNT(1) AS Number_of_Games, G.Round
FROM Game G
GROUP BY G.Round)
SELECT G.Round, SUM(P.goals / N.Number_of_Games) AS Average_goals_per_round
FROM Player P1,Game G INNER JOIN Plays P2 ON (P1.team = P2.away AND G.away = P2.away AND P1.yearofbirth >= '1993')
INNER JOIN Number_of_Games N ON (G.round = n.round)
GROUP BY g.round
ORDER BY g.round;
这里有一些测试数据:
INSERT INTO TEAM (ID, NAME, DISTRICT) VALUES ('MAN','MANCHESTER UNITED','MANCHESTER');
INSERT INTO TEAM (ID,NAME,DISTRICT) VALUES ('CHE','CHELSEA FC','LONDON');
INSERT INTO PLAYER (NICKNAME,NAME,YEAROFBIRTH,TEAM) VALUES('1','VAN PERSIE','1994','MAN');
INSERT INTO PLAYER (NICKNAME,NAME,YEAROFBIRTH,TEAM) VALUES('2','TERRY','1970','CHE');
INSERT INTO GAME(HOME,AWAY,ROUND,SPECTATORS) VALUES ('MAN','CHE','1','15000');
INSERT INTO GAME(HOME,AWAY,ROUND,SPECTATORS) VALUES ('CHE','MAN','2','30000');
INSERT INTO PLAYS(PLAYER,HOME,AWAY,GOALS) VALUES('1','MAN','CHE','2');
INSERT INTO PLAYS(PLAYER,HOME,AWAY,GOALS) VALUES('2','MAN','CHE','1');
INSERT INTO PLAYS(PLAYER,HOME,AWAY,GOALS) VALUES('1','CHE','MAN','1');
为什么这是错的?有人可以帮忙吗?
答案 0 :(得分:0)
查询1
球员及其球队的名字,他们总是在客场比赛
这将获得从未在家中玩过的球员的名字:
SELECT p.name AS player_name,
t.name AS team_name
FROM player p
INNER JOIN
team t
ON ( p.team = t.id )
WHERE NOT EXISTS ( SELECT 1
FROM plays l
WHERE p.nickname = l.player
AND p.team = l.home )
如果你想强制他们必须至少玩过一场比赛,那么:
SELECT p.name AS player_name,
t.name AS team_name
FROM player p
INNER JOIN
team t
ON ( p.team = t.id )
WHERE NOT EXISTS ( SELECT 1
FROM plays l
WHERE p.nickname = l.player
AND p.team = l.home )
AND EXISTS ( SELECT 1
FROM plays l
WHERE p.nickname = l.player
AND p.team = l.away -- Although you probably don't need this last line.
)
查询2
1993年以后出生但从未在家中出场的球员的平均进球数。
只考虑1993年以后出生并且从未在主场比赛过的球员所取得的进球,这应该得到每轮的平均进球数:
SELECT AVG( y.goals ),
g.round
FROM player p
INNER JOIN
plays y
ON ( p.nickname = y.player AND p.team = y.home )
INNER JOIN
game g
ON ( y.home = g.home AND y.away = g.away )
WHERE NOT EXISTS ( SELECT 1
FROM plays l
WHERE p.nickname = l.player
AND p.team = l.home )
AND p.yearOfBirth > 1993
GROUP BY g.round
ORDER BY g.round;
查询3
如果我想要目标人数最多的球队的身份证,我该怎么做?
可以使用:
回答WITH team_goals AS (
SELECT SUM( l.goals ) AS total_goals,
p.team,
CASE WHEN p.team = l.home THEN l.away
WHEN p.team = l.away THEN l.home
ELSE NULL
END AS opposing_team
FROM player p
INNER JOIN
plays l
ON (p.nickname = l.player)
GROUP BY
p.team,
CASE WHEN p.team = l.home THEN l.away
WHEN p.team = l.away THEN l.home
ELSE NULL
END
),
goals_against AS (
SELECT p.team,
SUM( q.total_goals ) AS total_goals_against
FROM team_goals p
INNER JOIN
team_goals q
ON ( p.team = q.opposing_team
AND p.opposing_team = q.team)
GROUP BY p.team
)
SELECT *
FROM goals_against
WHERE total_goals_against = ( SELECT MAX( total_goals_against )
FROM goals_against );
答案 1 :(得分:0)
NOT EXISTS应该帮助您解决第一个问题:
SELECT DISTINCT P1.Name, T.Name
FROM Player P1 JOIN team T ON p1.team = t.team
WHERE NOT EXISTS
(SELECT 1
FROM plays
WHERE player = p1.name
AND home = p1.team);
我尽量避免WHERE子句中的旧样式连接。使用ANSI 92连接语法以获得清晰度和扩展功能。
现在扩展此查询以仅包括1993年以后出生的那些玩家:
SELECT P1.Name, T.Name
FROM Player P1 JOIN team T ON p1.team = t.team
WHERE NOT EXISTS
(SELECT 1
FROM plays
WHERE player = p1.name
AND home = p1.team
AND year_of_birth <= 1993);
使用此查询查找平均值:
SELECT P1.Name, T.Name, g.round, AVG(p2.goals) "Average Goals"
FROM Player P1 JOIN team T ON p1.team = t.team
JOIN plays p2 ON p1.nickname = p2.player
JOIN game g ON p2.away = g.away
WHERE NOT EXISTS
(SELECT 1
FROM plays
WHERE player = p1.name
AND home = p1.team
AND year_of_birth <= 1993))
GROUP BY p1.name, t.name, g.round;
此外,在您的游戏和播放表格中,您不会为某些列的列定义提供TYPE。
这会让你走近。我还没有测试过。