I came across this problem recently, i’m a sql newbie preparing for an interview and i need some help understanding how to connect the tables without using joins (since there is no common column)to get the desired result
create table teams
(team_id integer not null,
team_name varchar(30) not null,
unique(team_id)
);
Team_id . Team_name
10 . Give
20 . Never
30 . You
40 . up
50 . Gonna
create table matches
(match_id integer not null,
host_team integer not null,
guest_team integer not null,
host_goals integer not null,
guest_goals integer not null,
unique(match_id)
);
Match_id Host_team Guest_team Host_goals Guest_goals
1 . 30 . 20 . 1 . 0
2 . 10 . 20 . 1 . 2
3 . 20 . 50 . 2 . 2
4 . 10 . 30 . 1 . 0
5 . 30 . 50 . 0 . 1
Compute the total number of points each team has scored after all the matches the rules are as follows
if a team wins a match(scores more goals than the other team) it gets 3 points.
if a team draws a match(scores exactly same number of goals as other team) it gets one point
if a team loses a match(scores fewer goals than other team) it gets no points.
write a query that returns a ranking of all teams(team_id) described in the table teams. for each team provide its name and number of points it received after all the matches(num_points). The table should be ordered by num_points in desc order. in case of a tie order the rows by team_id
Saw a solution that uses union all but it doesn’t provide the answer, tried modifying it myself too.
select a.team_id,a.team_name,3*count(1) from teams a, matches b
where a.team_id = b.host_team
and b.host_goals > b.guest_goals
group by a.team_id,a.team_name
union all
select a.team_id,a.team_name,count(1) from teams a, matches b
where a.team_id = b.host_team
and b.host_goals = b.guest_goals
group by a.team_id,a.team_name
union all
select a.team_id,a.team_name,3*count(1) from teams a, matches b
where a.team_id = b.guest_team
and b.host_goals < b.guest_goals
group by a.team_id,a.team_name
union all
select a.team_id,a.team_name,count(1) from teams a, matches b
where a.team_id = b.guest_team
and b.host_goals = b.guest_goals
group by a.team_id,a.team_name;
Solution should look like
team_id team_name num_points
20 Never 4
50 Gonna 4
10 Give 3
30 You 3
40 Up 0
Advertisement
Answer
I suggest the following:
WITH cteHostPoints AS (SELECT HOST_TEAM AS TEAM,
CASE
WHEN HOST_GOALS > GUEST_GOALS THEN 3
WHEN HOST_GOALS = GUEST_GOALS THEN 1
ELSE 0
END AS POINTS
FROM MATCHES),
cteGuestPoints AS (SELECT GUEST_TEAM AS TEAM,
CASE
WHEN GUEST_GOALS > HOST_GOALS THEN 3
WHEN GUEST_GOALS = HOST_GOALS THEN 1
ELSE 0
END AS POINTS
FROM MATCHES),
cteAllPoints AS (SELECT TEAM, POINTS FROM cteHostPoints
UNION ALL
SELECT TEAM, POINTS FROM cteGuestPoints)
SELECT t.TEAM_ID, t.TEAM_NAME, COALESCE(SUM(ap.POINTS), 0) AS TOTAL_POINTS
FROM TEAMS t
LEFT OUTER JOIN cteAllPoints ap
ON ap.TEAM = t.TEAM_ID
GROUP BY t.TEAM_ID, t.TEAM_NAME
ORDER BY COALESCE(SUM(POINTS), 0) DESC, t.TEAM_ID