带有join语句的sql中多行的总和
Posted
技术标签:
【中文标题】带有join语句的sql中多行的总和【英文标题】:Sum of multiple rows in sql with join statement 【发布时间】:2022-01-17 09:06:33 【问题描述】:我正在尝试对同一运动员的多行求和,以便返回他们总共赢得的奖牌总数。我有以下代码:
CREATE TABLE athlete (
athlete_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
country TINYTEXT NOT NULL,
birthdate DATE NOT NULL,
age INT UNSIGNED,
height_inch INT UNSIGNED,
PRIMARY KEY (athlete_id)
);
INSERT INTO athlete (name, country, birthdate, age, height_inch) VALUES ('Simone Biles', 'United States', '1997-03-14', 24, 56);
INSERT INTO athlete (name, country, birthdate, age, height_inch) VALUES ('Michael Phelps', 'United States', '1985-06-30', 36, 76);
CREATE TABLE sport (
sport_id INT UNSIGNED NOT NULL,
sport TINYTEXT NOT NULL,
PRIMARY KEY (sport_id)
);
INSERT INTO sport VALUES (101, 'Skiing');
INSERT INTO sport VALUES (102, 'Biathlon');
INSERT INTO sport VALUES (103, 'Curling');
INSERT INTO sport VALUES (104, 'Skating');
INSERT INTO sport VALUES (105, 'Ice Hockey');
INSERT INTO sport VALUES (106, 'Luge');
INSERT INTO sport VALUES (107, 'Snowboard');
INSERT INTO sport VALUES (108, 'Basketball');
INSERT INTO sport VALUES (109, 'Gymnastics');
INSERT INTO sport VALUES (110, 'Swimming');
INSERT INTO sport VALUES (111, 'Diving');
INSERT INTO sport VALUES (112, 'Track and Field');
INSERT INTO sport VALUES (113, 'Badminton');
INSERT INTO sport VALUES (114, 'Tennis');
INSERT INTO sport VALUES (115, 'Volleyball');
INSERT INTO sport VALUES (116, 'Skateboard');
INSERT INTO sport VALUES (117, 'Soccer');
INSERT INTO sport VALUES (118, 'Golf');
INSERT INTO sport VALUES (119, 'Cycling');
INSERT INTO sport VALUES (120, 'Climbing');
INSERT INTO sport VALUES (121, 'Surfing');
INSERT INTO sport VALUES (122, 'Water Polo');
INSERT INTO sport VALUES (123, 'Karate');
CREATE TABLE olympics (
olympics_id INT UNSIGNED NOT NULL,
season TINYTEXT NOT NULL,
year YEAR NOT NULL,
city TINYTEXT NOT NULL,
PRIMARY KEY (olympics_id)
);
INSERT INTO olympics VALUES (1001, 'Summer', 1936, 'Berlin');
INSERT INTO olympics VALUES (1002, 'Summer', 1956, 'Melbourne');
INSERT INTO olympics VALUES (1003, 'Summer', 1960, 'Rome');
INSERT INTO olympics VALUES (1004, 'Summer', 1964, 'Tokyo');
INSERT INTO olympics VALUES (1005, 'Summer', 1976, 'Montreal');
INSERT INTO olympics VALUES (1006, 'Summer', 1984, 'Los Angelos');
INSERT INTO olympics VALUES (1007, 'Summer', 1996, 'Atlanta');
INSERT INTO olympics VALUES (1008, 'Summer', 2000, 'Sydney');
INSERT INTO olympics VALUES (1009, 'Summer', 2004, 'Athens');
INSERT INTO olympics VALUES (1010, 'Summer', 2008, 'Beijing');
INSERT INTO olympics VALUES (1011, 'Summer', 2012, 'London');
INSERT INTO olympics VALUES (1012, 'Summer', 2016, 'Rio de Janeiro');
INSERT INTO olympics VALUES (1013, 'Summer', 2020, 'Tokyo');
CREATE TABLE sport_events (
sport_id INT UNSIGNED NOT NULL,
event_id INT UNSIGNED NOT NULL,
event TINYTEXT NOT NULL,
PRIMARY KEY (event_id),
FOREIGN KEY (sport_id) REFERENCES sport (sport_id)
);
INSERT INTO sport_events VALUES (101, 501, 'Alpine Skiing');
INSERT INTO sport_events VALUES (101, 502, 'Cross-Country Skiing');
INSERT INTO sport_events VALUES (104, 503, 'Figure Skating');
INSERT INTO sport_events VALUES (101, 504, 'Freestyle Skiing');
INSERT INTO sport_events VALUES (104, 505, 'Short Track Speed Skating');
INSERT INTO sport_events VALUES (101, 506, 'Ski Jumping');
INSERT INTO sport_events VALUES (107, 507, 'Half-pipe');
INSERT INTO sport_events VALUES (101, 508, 'Half-pipe');
INSERT INTO sport_events VALUES (104, 509, 'Speed Skating');
INSERT INTO sport_events VALUES (109, 510, 'Artistic Gymnastics');
INSERT INTO sport_events VALUES (109, 511, 'Rhythmic Gymnastics');
INSERT INTO sport_events VALUES (115, 512, 'Beach Volleyball');
INSERT INTO sport_events VALUES (112, 513, 'High Jump');
INSERT INTO sport_events VALUES (112, 514, '100m');
INSERT INTO sport_events VALUES (112, 515, '200m');
INSERT INTO sport_events VALUES (112, 516, '400m');
INSERT INTO sport_events VALUES (112, 517, '800m');
INSERT INTO sport_events VALUES (112, 518, '4x100m relay');
INSERT INTO sport_events VALUES (112, 519, 'Triple Jump');
CREATE TABLE athlete_sport (
athlete_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
sport_id INT UNSIGNED NOT NULL,
PRIMARY KEY (athlete_id),
FOREIGN KEY (athlete_id) REFERENCES athlete (athlete_id),
FOREIGN KEY (sport_id) REFERENCES sport (sport_id)
);
INSERT INTO athlete_sport (sport_id) VALUES (109);
INSERT INTO athlete_sport (sport_id) VALUES (110);
CREATE TABLE compete (
athlete_id INT UNSIGNED NOT NULL,
olympics_id INT UNSIGNED NOT NULL,
sport_id INT UNSIGNED NOT NULL,
event_id INT UNSIGNED,
gold INT UNSIGNED,
silver INT UNSIGNED,
bronze INT UNSIGNED,
FOREIGN KEY (olympics_id) REFERENCES olympics (olympics_id),
FOREIGN KEY (athlete_id) REFERENCES athlete (athlete_id),
FOREIGN KEY (event_id) REFERENCES sport_events (event_id)
);
INSERT INTO compete VALUES (1, 1012, 109, 510, 4, 0, 1);
INSERT INTO compete VALUES (1, 1013, 109, 510, 0, 1, 1);
INSERT INTO compete VALUES (2, 1009, 110, NULL, 6, 0, 2);
INSERT INTO compete VALUES (2, 1010, 110, NULL, 8, 0, 0);
INSERT INTO compete VALUES (2, 1011, 110, NULL, 4, 2, 0);
INSERT INTO compete VALUES (2, 1012, 110, NULL, 5, 1, 0);
我查看了人们发布的其他答案,他们中的大多数人只是说要使用 group by,但是当我使用它时,它只是以不同的顺序将名称或奖牌数量排列在一起。我正在努力得到它,所以它说 simone bilis 的奖牌总数是 7 枚,michael phelps 是 28 枚,仅在一张桌子上。
这是我的查询,它返回他们参加过的每场奥运会的奖牌总和,但如果我再次使用 group by 它只是订购它们。
select a.name, gold+silver+bronze as medalTotal from athlete a join compete c using (athlete_id) group by medalTotal;
+----------------+------------+
| name | medalTotal |
+----------------+------------+
| Simone Biles | 2 |
| Simone Biles | 5 |
| Michael Phelps | 6 |
| Michael Phelps | 8 |
+----------------+------------+
【问题讨论】:
你应该按名字分组,而不是奖牌总数。 这将使迈克尔·菲尔普斯获得 8 枚奖牌,西蒙娜·比尔斯获得 5 枚奖牌,但它仍然不能总结一切。 您需要使用SUM()
在组中跨行添加值。
谢谢,我不确定它是否会与其中的添加一起工作,但确实可以。
【参考方案1】:
您需要执行以下操作:
按运动员分组 总结每种奖牌类型 将每种奖牌类型的总和相加【讨论】:
【参考方案2】:您需要按运动员分组,而不是总数。
您必须使用聚合函数来组合组中所有行的值。使用SUM()
将它们加在一起。
select a.name, SUM(b.gold+b.silver+b.bronze) as medalTotal
from athlete a
join compete c using (athlete_id)
group by a.athlete_id;
【讨论】:
【参考方案3】:您应该使用独特的东西(例如 athelet id)来应用组。
这将获得所有奖牌号码包括零奖牌的所有运动员 如果您只想获得奖牌,请仅使用加入。
select
a.name, sum(gold+silver+bronze) as medalTotal
from
athlete a
left join
compete c on c.athlete_id = a.athlete_id
group by
a.athlete_id
【讨论】:
以上是关于带有join语句的sql中多行的总和的主要内容,如果未能解决你的问题,请参考以下文章
请高手解答几个sql的join的问题的疑惑。我用的是MSSqlserver。