Removing an item from the result if it has a particular parameter somewhere in the table - mysql

I've been looking all around stack overflow and can't seem to find a question like this but its probably super simple and has been asked a million times. So I am sorry if my insolence offends you guys.
I want to remove an attribute from the result if it appears anywhere in the table.
Here is an example: I want display every team that does not have a pitcher. This means I don't want to display 'Phillies' with the rest of the results.
Example of table:
Here is the example of the code I have currently have where Players is the table.
SELECT DISTINCT team
FROM Players
WHERE position ='Pitcher' Not IN
(SELECT DISTINCT position
FROM Players)
Thanks for any help you guys can provide!

You can use NOT EXISTS() :
SELECT DISTINCT s.team
FROM Players s
WHERE NOT EXISTS(SELECT 1 FROM Players t
where t.team = s.team
and position = 'Pitcher')
Or with NOT IN:
SELECT DISTINCT t.team
FROM Players t
WHERE t.team NOT IN(SELECT s.team FROM Players s
WHERE s.position = 'Pitcher')
And a solution with a left join:
SELECT distinct t.team
FROM Players t
LEFT OUTER JOIN Players s
ON(t.team = s.team and s.position = 'pitcher')
WHERE s.team is null

Use NOT EXISTS
Query
select distinct team
from players p
where not exists(
select * from players q
where p.team = q.team
and q.position = 'Pitcher'
);

Probably the easiest way to approach this problem is to aggregate players over team:
select team
from players
group by team
having sum(case when position = 'Pitcher' then 1 else 0 end) = 0;
The big advantage is that you'd read the table only once.
Another advantage is that you can easily adjust the HAVING clause to have more elaborate queries, e.g. get all teams that have at least one catcher, two outfielders, and no pitcher.

Related

top 10 scorers by season

How I can get top 10 scorers by seasons.
So it shows last season top 10 scorers...
I've tryed left join into table, but it goes broken showing 2 player and counts all goals to first player.
My sqlfiddle:
http://sqlfiddle.com/#!9/b5d0a78/1
You got it almost right.
You want to group match_goals by player ID (match_player_id), but then you should not select goal_minute or any other per goal data.
After grouping by player, then you can create a column for COUNT(match_player_id) this will give you the number of goals, you can also use this column to order the results.
Your joins and conditions are correct I think.
EDIT
I think your schema needs a few tweaks: check this http://sqlfiddle.com/#!9/f5a75b/2
Basically create direct relations in the match_players and match_goals to the other tables.
I think the query you want looks like this:
SELECT p.*, count(*) as num_goals
FROM match_goals g INNER JOIN
match_players p
ON g.match_player_id = p.id INNER JOIN
matches m
ON m.id = p.match_id
WHERE p.is_deleted = 0 AND
g.is_own_goal = 0 AND
m.seasion_id = <last season id>
GROUP BY p.id
ORDER BY num_goals DESC
LIMIT 10;
Note that the teams table is not needed. The SELECT p.* is allowed because p.id (the GROUP BY key) is unique.

MySQL view subquery with custom where clause?

I am trying to design a view on a MySQL database that stores information about football (soccer).
My goal is to create a view that returns all the goals and the basic information of the scorers. This is a simplified version of what the view used to look like:
SELECT P.Name AS Player,
P.TeamName AS Team,
(SELECT COUNT(*)
FROM Goals G
WHERE G.Scorer = P.playerID) AS TotalGoals
FROM Players P
So far, everything's right. The problem started when I wanted to count goals only within a certain season, specified in the WHERE clause, as I show below:
SELECT * FROM GoalsView WHERE Season = 1
And for it to return automatically only the count of the goals of the season in WHERE clause, as if the subquery was automatically edited to make it look like:
[...]
(SELECT COUNT(*)
FROM Goals G
WHERE G.Scorer = P.playerID
AND Season=1) AS TotalGoals
[...]
I hope I made myself clear. Thanks for your help!
One possible solution is
SELECT P.Name AS Player,
P.TeamName AS Team,
(SELECT COUNT(*)
FROM Goals G
WHERE G.Scorer = P.playerID AND season=1 GROUP By season) AS TotalGoals
FROM Players P
I don't know whether you have separate table for season or a column
In order to have access to goals.season, you must join the two tables:
select
p.name as player,
p.teamname as team,
count(goals.id) as totalgoals
from players p
left join goals g on g.scorer = p.playerid
group by p.name, p.teamname;

How to count the teams with no foreign players

I have a table for the football clubs of a country. The fields are "teamName", "playerName", and "country".
I'd like to count the clubs that all their players are foreigners
. I tried the following query but I think it's not working since it seems that it counts when we have at least one foreigner but I want it to count if all the players of a team are foreigners!
SELECT COUNT(DISTINCT teamName)
FROM teams
WHERE country not like '%England%'
Please advise. Thanks!
One way would be:
SELECT COUNT(DISTINCT teamName)
FROM teams T1
WHERE NOT EXISTS
( select * from teams T2
WHERE T1.teamName=T2.teamName and T2.country like '%England%')
Hmm even join seems to need an inner query:
SELECT COUNT(*)
FROM (
SELECT teamName,
SUM(country like '%England%') AS Locals
FROM teams
GROUP BY teamName
) AS t
WHERE Locals = 0;
Seems like there should be a shorter answer though...
Quick and dirty answer, and it does only one pass through the data, no subquery. This selects teams that are all foreign. You can play with the CASE expression if that is not what you want.
SELECT team_name
FROM teams
GROUP BY team_name
HAVING COUNT(country)=
SUM(CASE country != 'England' WHEN TRUE THEN 1 ELSE 0 END);
Longer answer: Your schema is not normalized, but should be. You want want table of teams and a second table of players, which includes a foreign key into the team table for that player's current team. This is basic DB normalization. However, replacing the single table in the FROM with the join of those two tables, the same GROUP BY/HAVING trick works.

calculating player statistics from database

i have the following tables.
i want to fetch all the player statistics record from the given tables, the records of individual player includes.
Player Name
Position
Total Number of games played
Number of goals scored
Total number of assist for goals.
Total Points (total goals + total assist = total points).
after trying i came up with this query
SELECT SQL_CALC_FOUND_ROWS
CONCAT(u.first_name, ' ', u.last_name) as player_name,
p.position,
COUNT(g.id)
FROM
gce_player p
LEFT JOIN
gce_user u ON(u.id = p.user_id)
LEFT JOIN
gce_game_team_lineup gtl ON(gtl.player_id = p.id)
LEFT JOIN
gce_game_team gt ON(gt.id = gtl.game_team_id)
LEFT JOIN
gce_game_goal gg ON(gg.player_id = p.id)
LEFT JOIN
gce_game g ON(g.id = gt.game_id)
GROUP BY p.id
ORDER BY p.id asc
the above query returns me proper record till total number of games played, i am facing issue fetching the proper records after this, ill appreciate any kind of help on this.
here is the link to sqlfiddle if you want to look at the schema, i have added some test data too.
thank you.
UPDATE :
here are few of the rules to remember.
Number of goals scored = total number of goals scored by a player. for example if in gce_game_goal table there are 10 rows which have
the value of player_id as 4 it means the player have scored 10 goals
and i need to fetch this record for individual player, and
likewise if there are 7 rows in which player_id have value of 3 this
means player with id 3 have scored 7 goals and likewise.
Total number of assist for goals = total number of assist given to a goalie by a player (assist is like a pass in football). i need to
calculate total number of assist or pass that was done by a user.
for each goal there will be two assist, and each assist are players
who pass the ball to a golaie. i want to count the number of passes
or assist given by a player. for example if in gce_game_goal
table there are 8 rows or records that have the value of 3 in either
assis1_id or assist2_id column, this means player with id 3 have
scored 8 assist in total
.
kindly let me know if you still have any doubts/question, ill try to improve my question
Thanks
The problem that you are facing is caused by aggregating along multiple different dimensions of the data (say by game and by goal). This results in a cross product for each player.
A fairly general solution is to do aggregations in the from clause, along each dimension. Each variable (or perhaps a few variables) comes from a different aggregation:
select u.last_name, u.first_name, p.position,
pg.goals, pg.assists, (pg.goals + pg.assists) as TotalPoints
from gce_player p join
gce_user u
on p.user_id = u.id left outer join
(select player_id, SUM(goal) as goals, SUM(assist) as assists
from ((select player_id, 1 as goal, 0 as assist
from gce_game_goal
) union all
(select assist1_id, 0 as goal, 1 as assist
from gce_game_goal
) union all
(select assist2_id, 0 as goal, 1 as assist
from gce_game_goal
)
) t
group by player_id
) pg
on pg.player_id = p.id left outer join
(select gtl.player_id, count(*) as NumTeams
from gce_game_team_lineup gtl join
gce_game_team gt
on gtl.id = gt.team_id
) g
on g.player_id = p.id
Try this
SELECT
CONCAT(u.first_name, ' ', u.last_name) as player_name,
count(g.id) as Goals,
(select
count(*)
from
gce_game_goal
where
assist1_id = p.player_id)
+(select
count(*)
from
gce_game_goal
where
assist2_id = p.player_id) as Assists,
count(g.id)
+ (select
count(*)
from
gce_game_goal
where
assist1_id = p.player_id)
+ (select
count(*)
from
gce_game_goal
where
assist2_id = p.player_id) as Total
FROM
gce_player as p
LEFT JOIN
gce_game_goal as g ON p.id = g.player_id
LEFT JOIN
gce_user u ON(u.id =p.user_id)
GROUP BY p.player_id

Left join, how to specify 1 result from the right?

This one is fairly specific, so I'm hoping for a quick fix.
I have a single result in my leaderboard table for each team. In my teams table, I have several results for each team (one result per game to enable team development history).
I want to show each team in the leaderboard once, and have teamID replaced by strName. Problem is, my left join is giving me one record for each team result; I just want a single record.
SELECT * , a.strName AS teamName
FROM bb_leaderboards l
LEFT JOIN bb_teams a ON ( l.teamID = a.ID )
WHERE l.season =8
AND l.division =1
ORDER BY l.division DESC , points DESC , wins DESC , l.TDdiff DESC
LIMIT 0 , 30
What do I need to do to this to get a 1:1 output?
You could do a SELECT DISTINCT instead, but you'll have to narrow down your select a bit. So:
SELECT DISTINCT l.*, a.strName AS teamName
...
That should filter out the duplicates.