棘手的 MySQL 视图
Tricky MySQL view
我发现在 MySQL 中创建视图非常困难,希望有人能帮助我。这是我的数据库的架构:
CREATE DATABASE football;
CREATE TABLE `team` (
`name` varchar(15) PRIMARY KEY NOT NULL
);
CREATE TABLE `season` (
`name` char(9) PRIMARY KEY NOT NULL,
`begin` date,
`end` date);
CREATE TABLE `game` (
`id` int PRIMARY KEY NOT NULL AUTO_INCREMENT,
`Date` date DEFAULT NULL,
`HomeTeam` varchar(15) NOT NULL,
`AwayTeam` varchar(15) NOT NULL,
`FTHG` int DEFAULT NULL, (full time home goal)
`FTAG` int DEFAULT NULL, (full time away goal)
`FTR` char(1) DEFAULT NULL,
`HTHG` int DEFAULT NULL,
`HTAG` int DEFAULT NULL,
`HTR` char(1) DEFAULT NULL,
`H_S` int DEFAULT NULL,
`A_S` int DEFAULT NULL,
`HST` int DEFAULT NULL,
`AST` int DEFAULT NULL,
`HC` int DEFAULT NULL,
`AC` int DEFAULT NULL,
`HF` int DEFAULT NULL,
`AF` int DEFAULT NULL,
`HY` int DEFAULT NULL,
`AY` int DEFAULT NULL,
`HR` int DEFAULT NULL,
`AR` int DEFAULT NULL,
`season` char(9),
FOREIGN KEY (HomeTeam) REFERENCES team(name),
FOREIGN KEY (AwayTeam) REFERENCES team(name),
FOREIGN KEY (season) REFERENCES season(name),
CHECK (HomeTeam != AwayTeam)
);
该数据库收集了一系列足球比赛和每场比赛的许多特征,以及所有球队和赛季。
由于这种观点 (),我能够生成每个赛季的积分、进球数和失球数:
CREATE VIEW stats AS
(SELECT season,team,sum(TGS) TGS,sum(TGC) TGC,sum(pts) pts
FROM (SELECT season, HomeTeam team, FTHG TGS, FTAG TGC,
CASE WHEN FTHG > FTAG THEN 3 WHEN FTHG=FTAG THEN 1 ELSE 0 END pts
FROM game UNION ALL SELECT season, AwayTeam team, FTAG TGS, FTHG TGC,
CASE WHEN FTAG > FTHG THEN 3 WHEN FTAG=FTHG THEN 1 ELSE 0 END pts FROM game) games
GROUP BY season,team);
结果如下:
SELECT * FROM stats;
View 列依次为:赛季、球队、TGS(球队得分)、TGC(球队失球)
太好了,但我现在需要的是生成排名。理想情况下,我想要如下内容:
Team,19,18,17,16,15,14 (years)
Juventus,1,1,1,1,1,1 (came first each year)
Inter,2,4,4,7,4,8
Atalanta,3,3,7,4,13,17
Lazio,4,8,5,5,8,3
Roma,5,6,3,2,3,2
Milan,6,5,6,6,7,10
Napoli,7,2,2,3,2,5
Sassuolo,8,11,11,10,6,12
Verona,9,,19,,,13
一个主要的困难是,如您所见,排名来自第 14 年(2014-2015 赛季)。因此,此数据不存在于数据库中。虽然这是一件坏事,但是否可以在视图中对其进行硬编码?我总是需要每场比赛前一年的数据,所以添加旧游戏只会重现问题......
此外,应排除当前季节(在示例中,将当前季节视为 2020-2021)。
感谢任何帮助或建议!
备注
我知道数据库结构可能不是最好的,但我现在必须坚持使用它...
为什么不只计算当前视图中每个球队/赛季的排名。现在您可以根据需要加入任何级别(和任何赛季)。
如果您需要上一年的排名,我们可以在后续表达式中使用 LAG 来做到这一点,或者只是根据与年份相关的一些表达式进行连接。
注意 select 列表中的 RANK
表达式。
建议(针对MySQL 8.0+):
CREATE VIEW stats AS
SELECT season, team
, sum(TGS) TGS, sum(TGC) TGC, sum(pts) pts
, RANK() OVER (PARTITION BY season ORDER BY SUM(pts) DESC) AS rnk
FROM (
SELECT season, HomeTeam team, FTHG TGS, FTAG TGC
, CASE WHEN FTHG > FTAG THEN 3 WHEN FTHG = FTAG THEN 1 ELSE 0 END pts
FROM game
UNION ALL
SELECT season, AwayTeam team, FTAG TGS, FTHG TGC
, CASE WHEN FTAG > FTHG THEN 3 WHEN FTAG = FTHG THEN 1 ELSE 0 END pts
FROM game
) games
GROUP BY season, team
;
我发现在 MySQL 中创建视图非常困难,希望有人能帮助我。这是我的数据库的架构:
CREATE DATABASE football;
CREATE TABLE `team` (
`name` varchar(15) PRIMARY KEY NOT NULL
);
CREATE TABLE `season` (
`name` char(9) PRIMARY KEY NOT NULL,
`begin` date,
`end` date);
CREATE TABLE `game` (
`id` int PRIMARY KEY NOT NULL AUTO_INCREMENT,
`Date` date DEFAULT NULL,
`HomeTeam` varchar(15) NOT NULL,
`AwayTeam` varchar(15) NOT NULL,
`FTHG` int DEFAULT NULL, (full time home goal)
`FTAG` int DEFAULT NULL, (full time away goal)
`FTR` char(1) DEFAULT NULL,
`HTHG` int DEFAULT NULL,
`HTAG` int DEFAULT NULL,
`HTR` char(1) DEFAULT NULL,
`H_S` int DEFAULT NULL,
`A_S` int DEFAULT NULL,
`HST` int DEFAULT NULL,
`AST` int DEFAULT NULL,
`HC` int DEFAULT NULL,
`AC` int DEFAULT NULL,
`HF` int DEFAULT NULL,
`AF` int DEFAULT NULL,
`HY` int DEFAULT NULL,
`AY` int DEFAULT NULL,
`HR` int DEFAULT NULL,
`AR` int DEFAULT NULL,
`season` char(9),
FOREIGN KEY (HomeTeam) REFERENCES team(name),
FOREIGN KEY (AwayTeam) REFERENCES team(name),
FOREIGN KEY (season) REFERENCES season(name),
CHECK (HomeTeam != AwayTeam)
);
该数据库收集了一系列足球比赛和每场比赛的许多特征,以及所有球队和赛季。
由于这种观点 (
CREATE VIEW stats AS
(SELECT season,team,sum(TGS) TGS,sum(TGC) TGC,sum(pts) pts
FROM (SELECT season, HomeTeam team, FTHG TGS, FTAG TGC,
CASE WHEN FTHG > FTAG THEN 3 WHEN FTHG=FTAG THEN 1 ELSE 0 END pts
FROM game UNION ALL SELECT season, AwayTeam team, FTAG TGS, FTHG TGC,
CASE WHEN FTAG > FTHG THEN 3 WHEN FTAG=FTHG THEN 1 ELSE 0 END pts FROM game) games
GROUP BY season,team);
结果如下:
SELECT * FROM stats;
View 列依次为:赛季、球队、TGS(球队得分)、TGC(球队失球)
太好了,但我现在需要的是生成排名。理想情况下,我想要如下内容:
Team,19,18,17,16,15,14 (years)
Juventus,1,1,1,1,1,1 (came first each year)
Inter,2,4,4,7,4,8
Atalanta,3,3,7,4,13,17
Lazio,4,8,5,5,8,3
Roma,5,6,3,2,3,2
Milan,6,5,6,6,7,10
Napoli,7,2,2,3,2,5
Sassuolo,8,11,11,10,6,12
Verona,9,,19,,,13
一个主要的困难是,如您所见,排名来自第 14 年(2014-2015 赛季)。因此,此数据不存在于数据库中。虽然这是一件坏事,但是否可以在视图中对其进行硬编码?我总是需要每场比赛前一年的数据,所以添加旧游戏只会重现问题...... 此外,应排除当前季节(在示例中,将当前季节视为 2020-2021)。 感谢任何帮助或建议!
备注
我知道数据库结构可能不是最好的,但我现在必须坚持使用它...
为什么不只计算当前视图中每个球队/赛季的排名。现在您可以根据需要加入任何级别(和任何赛季)。
如果您需要上一年的排名,我们可以在后续表达式中使用 LAG 来做到这一点,或者只是根据与年份相关的一些表达式进行连接。
注意 select 列表中的 RANK
表达式。
建议(针对MySQL 8.0+):
CREATE VIEW stats AS
SELECT season, team
, sum(TGS) TGS, sum(TGC) TGC, sum(pts) pts
, RANK() OVER (PARTITION BY season ORDER BY SUM(pts) DESC) AS rnk
FROM (
SELECT season, HomeTeam team, FTHG TGS, FTAG TGC
, CASE WHEN FTHG > FTAG THEN 3 WHEN FTHG = FTAG THEN 1 ELSE 0 END pts
FROM game
UNION ALL
SELECT season, AwayTeam team, FTAG TGS, FTHG TGC
, CASE WHEN FTAG > FTHG THEN 3 WHEN FTAG = FTHG THEN 1 ELSE 0 END pts
FROM game
) games
GROUP BY season, team
;