MySQL 查询以执行 SELF 连接并执行聚合
MySQL query to do a SELF join and perform aggregation
我需要从 mysql 数据库获取数据。
下面是 DDL、DML、示例输出和查询。
我需要有关优化查询的帮助,因为我确定我编写的查询非常基础。
create table team (
team_id int,
team_name char(10)
);
create table matches (
matches_id int,
host_team_id int,
guest_team_id int,
host_goals int,
guest_goals int
);
insert into team values (10, 'mumbai');
insert into team values (20, 'delhi');
insert into team values (30, 'banglore');
insert into team values (40, 'chennai');
insert into team values (50, 'gujarat');
insert into matches values (1, 50, 20, 2,1);
insert into matches values (2, 30, 40, 2,0);
insert into matches values (3, 10, 50, 1,1);
insert into matches values (4, 20, 30, 0,1);
insert into matches values (5, 40, 20, 3,2);
insert into matches values (6, 50, 30, 1,0);
insert into matches values (7, 40, 10, 1,2);
--规则
-- 进球多的球队获胜并获得3分
-- 输的队伍得0分
-- 平局,每队得 1 分
预期输出[按目标排序然后按team_name
team_id | team_name | goals
50 gujarat 7
30 bangalore 6
10 mumbai 4
40 chennai 3
20 delhi 0
查询
select * from (select team_id, team_name, sum(goals) as goals from (
select team_id, team_name,
SUM( Case
when host_goals > guest_goals then 3
when host_goals = guest_goals then 1
else 0
end ) as goals
from team t , matches m1
where t.team_id = m1.host_team_id
group by team_id, team_name
union all
select team_id, team_name,
SUM( Case
when guest_goals > host_goals then 3
when host_goals = guest_goals then 1
else 0
end ) as goals
from team t , matches m1
where t.team_id = m1.guest_team_id
group by team_id, team_name
order by goals desc, team_name asc) as finalOut
group by team_id, team_name ) as t1
order by goals desc, team_name asc
您应该只对最外部的 select
执行求和、分组依据和排序依据
select * from (select team_id, team_name, sum(goals) as goals from (
select
team_id
, team_name
, Case
when host_goals > guest_goals then 3
when host_goals = guest_goals then 1
else 0
end as goals
from team t
Inner join matches m1 on t.team_id = m1.host_team_id
union all
select
team_id
, team_name
, Case
when guest_goals > host_goals then 3
when host_goals = guest_goals then 1
else 0
end
from team t
inner join matches m1 on t.team_id = m1.guest_team_id
) as finalOut
group by team_id, team_name
order by goals desc, team_name asc
我会进行彻底的简化:
select t.team_id, t.team_name, sum(points) as points
from teams t join
((select host_team_id as team_id, host_goals as goals, 'host' as which,
(case when host_goals > guest_goals then 3
when host_goals = guest_goals then 1
else 0
end) as points
from matches
) union all
(select guest_team_id as team_id, guest_goals as goals, 'guest' as which
(case when guest_goals > host_goals then 3
when guest_goals = host_goals then 1
else 0
end) as points
from matches
)
) hg
on hg.team_id = t.team_id
group by t.team_id, t.team_name
order by sum(points) desc, team_name;
如果您想要所有球队——甚至是那些没有参加过比赛的球队——然后使用 left join
。
使用更好的标准,而不必 union
两次查询。忘记 union all
并执行此操作:
select team_id, team_name,
SUM(
(t.team_id = m1.host_team_id) * ((host_goals >= guest_goals) + 2 * (host_goals > guest_goals)) +
(t.team_id = m1.guest__team_id) * ((host_goals <= guest_goals) + 2 * (host_goals < guest_goals))
) as goals
from team t , matches m1
where ((t.team_id = m1.host_team_id) or (t.team_id = m1.guest_team_id))
group by team_id, team_name
这应该是一个很好的起点。 (未经测试)
我需要从 mysql 数据库获取数据。 下面是 DDL、DML、示例输出和查询。 我需要有关优化查询的帮助,因为我确定我编写的查询非常基础。
create table team (
team_id int,
team_name char(10)
);
create table matches (
matches_id int,
host_team_id int,
guest_team_id int,
host_goals int,
guest_goals int
);
insert into team values (10, 'mumbai');
insert into team values (20, 'delhi');
insert into team values (30, 'banglore');
insert into team values (40, 'chennai');
insert into team values (50, 'gujarat');
insert into matches values (1, 50, 20, 2,1);
insert into matches values (2, 30, 40, 2,0);
insert into matches values (3, 10, 50, 1,1);
insert into matches values (4, 20, 30, 0,1);
insert into matches values (5, 40, 20, 3,2);
insert into matches values (6, 50, 30, 1,0);
insert into matches values (7, 40, 10, 1,2);
--规则
-- 进球多的球队获胜并获得3分 -- 输的队伍得0分 -- 平局,每队得 1 分
预期输出[按目标排序然后按team_name
team_id | team_name | goals
50 gujarat 7
30 bangalore 6
10 mumbai 4
40 chennai 3
20 delhi 0
查询
select * from (select team_id, team_name, sum(goals) as goals from (
select team_id, team_name,
SUM( Case
when host_goals > guest_goals then 3
when host_goals = guest_goals then 1
else 0
end ) as goals
from team t , matches m1
where t.team_id = m1.host_team_id
group by team_id, team_name
union all
select team_id, team_name,
SUM( Case
when guest_goals > host_goals then 3
when host_goals = guest_goals then 1
else 0
end ) as goals
from team t , matches m1
where t.team_id = m1.guest_team_id
group by team_id, team_name
order by goals desc, team_name asc) as finalOut
group by team_id, team_name ) as t1
order by goals desc, team_name asc
您应该只对最外部的 select
执行求和、分组依据和排序依据 select * from (select team_id, team_name, sum(goals) as goals from (
select
team_id
, team_name
, Case
when host_goals > guest_goals then 3
when host_goals = guest_goals then 1
else 0
end as goals
from team t
Inner join matches m1 on t.team_id = m1.host_team_id
union all
select
team_id
, team_name
, Case
when guest_goals > host_goals then 3
when host_goals = guest_goals then 1
else 0
end
from team t
inner join matches m1 on t.team_id = m1.guest_team_id
) as finalOut
group by team_id, team_name
order by goals desc, team_name asc
我会进行彻底的简化:
select t.team_id, t.team_name, sum(points) as points
from teams t join
((select host_team_id as team_id, host_goals as goals, 'host' as which,
(case when host_goals > guest_goals then 3
when host_goals = guest_goals then 1
else 0
end) as points
from matches
) union all
(select guest_team_id as team_id, guest_goals as goals, 'guest' as which
(case when guest_goals > host_goals then 3
when guest_goals = host_goals then 1
else 0
end) as points
from matches
)
) hg
on hg.team_id = t.team_id
group by t.team_id, t.team_name
order by sum(points) desc, team_name;
如果您想要所有球队——甚至是那些没有参加过比赛的球队——然后使用 left join
。
使用更好的标准,而不必 union
两次查询。忘记 union all
并执行此操作:
select team_id, team_name,
SUM(
(t.team_id = m1.host_team_id) * ((host_goals >= guest_goals) + 2 * (host_goals > guest_goals)) +
(t.team_id = m1.guest__team_id) * ((host_goals <= guest_goals) + 2 * (host_goals < guest_goals))
) as goals
from team t , matches m1
where ((t.team_id = m1.host_team_id) or (t.team_id = m1.guest_team_id))
group by team_id, team_name
这应该是一个很好的起点。 (未经测试)