ceno980
ceno980

Reputation: 2011

SQL: Find country name of the team having the most players who have never scored a goal

I have the following tables:

create table Players (
id integer,
name varchar(50) not null,
birthday date,
memberOf integer not null,
position varchar(20).
primary key (id),
foreign key (memberOf) references Teams(id)
);

create table Goals (
id integer,
scoredIn integer not null,
scoredBy integer not null,
timeScored integer not null,
rating varchar(20),
primary key (id),
foreign key (scoredIn) references Matches(id),
foreign key (scoredBy) references Players(id)
);

create table Teams (
id integer,
country varchar(50) not null,
primary key (id)
);

I have the following data in the above tables:

PLAYERS:

id       |    name     |     birthday     |     memberof    |     position
7           Mina            1997-01-20         1                 Captain
9           John            1997-09-01         1                 Quarterback 
2           Minnie          1995-10-13         3                 Goalkeeper
13          Lisa            1997-03-27         4                 Captain 
12          Rina            1995-01-03         2                 Fullback
11          Jasper          2002-09-22         1                 Halfback
17          Rose            1997-02-11         1                 Goalkeeper
22          Parvin          1993-03-09         3                 Goalkeeper
25          Nasom           1996-12-29         3                 Fullback

GOALS:

id    |     scoredin    |    scoredby    |    timescored     |     rating
1           10               7                60                   amazing
2           10               7                30                   okay
3           10               7                90                   amazing
4           20               9                119                  nice
5           20               9                80                   amazing
6           20               9                75                   amazing
7           30               2                30                   nice 
8           30               2                90                   amazing
9           40               13               110                  amazing

TEAMS:

id    |    country
1          Australia
2          Malaysia
3          Japan
4          Thailand

I am trying to output the country name of the team which has the most players who have never scored a goal. The output should be:

Country     |     Players 
Australia         2
Japan             2

I have the following view, which gives the count of players who have never scored a goal for each country:

create or replace view zerogoals as
select t.country, count(*)
from (
select distinct p.id, p.name, p.memberof, g.scoredby
from players p
full outer join goals g
on p.id = g.scoredby where scoredby is null
) s
inner join teams t on t.id = s.memberof group by t.country;

The above query gives me the following output:

country    |     count
Australia        2
Japan            2
Malaysia         1

I tried using the max function to get the desired output:

select country, max(count)
from zerogoals
group by country;

However I get the following output:

country    |    max
Australia       2
Japan           2
Malaysia        1

I am not sure how to get the tuples in the view zerogoals with the maximum value for the attribute count. Any insights are appreciated.

Upvotes: 1

Views: 7791

Answers (4)

george iosifidis
george iosifidis

Reputation: 1

SELECT DISTINCT(player)
  FROM game JOIN goal ON matchid = id 
    WHERE (team1='GER' AND team2!='GER' OR team1!='GER' AND team2='GER') AND teamid!= 'GER'

It not that pretty but it works.

Upvotes: 0

Gordon Linoff
Gordon Linoff

Reputation: 1270743

To get the number of players per country with no goal, you can use:

select t.name, count(*) as num_players_no_goal
from team.t join
     player p
     on t.id = p.memberof
where not exists (select 1
                  from goals g
                  where g.scoredby = p.id
                 )
group by t.name;

To limit this to just the maximum number, use window functions:

select name, num_players_no_goal
from (select t.name, count(*) as num_players_no_goal,
             rank() over (order by count(*) desc) as seqnum
      from team.t join
           player p
           on t.id = p.memberof
      where not exists (select 1
                        from goals g
                        where g.scoredby = p.id
                       )
      group by t.name
     ) t
where seqnum = 1;

One slight caveat is that this returns no teams if all players on all teams have scored goals. It is easily modified for that situation, but I'm guessing that you would rather return zero teams than all teams if that were the case.

Upvotes: 0

forpas
forpas

Reputation: 164174

You can use a CTE:

with cte as (
  select
    t.id, t.country, count(*) players 
  from teams t inner join (
    select * from players 
    where id not in (select scoredby from goals)
  ) p on p.memberOf = t.id
  group by t.id, t.country
)
select country, players 
from cte
where players = (select max(players) from cte)
order by country

See the demo.
Results:

country   | players 
Australia |       2
Japan     |       2

Upvotes: 0

ScaisEdge
ScaisEdge

Reputation: 133400

You could try using a inner join between the player, team and the list of not in goals ordered by count and limit to 1

select  t.name , count(*)
from player p
INNER JOIN  team t ON t.id = p.memberof
inner join (
select  p.id 
from  PLAYERS p 
where p.id  NOT IN  (
  select scoredby 
  from GOALS
) ) t1 on t1.id  = p.id 
group by t.name 
order by count(*) desc 
limit 1 

if you want all the max then

select  t.name , count(*)
from player p
INNER JOIN  team t ON t.id = p.memberof
inner join (
select  p.id 
from  PLAYERS p 
where p.id  NOT IN  (
  select scoredby 
  from GOALS
) t1 on t1.id  = p.id 
group by t.name 
having  count(*) = (
select  t.name , count(*)
from player p
INNER JOIN  team t ON t.id = p.memberof
inner join (
select  p.id 
from  PLAYERS p 
where p.id  NOT IN  (
  select scoredby 
  from GOALS
) t1 on t1.id  = p.id 
group by t.name 
 order by count(*) 
 limit 1 
)

Upvotes: 0

Related Questions