MySQL query for an MLB database - mysql

There are 5 tables: mlb_batting, mlb_manager, mlb_master, mlb_pitching, mlb_team.
Find the top 10 (highest) “strike outs per walk” statistic for all pitches with at least 1 walk that played in at least 25 games. You should display their first name, last name, and K/BB statistic. K/BB is computed by dividing the number of strike outs by the number of walks (“base on balls”). You will need to use “limit” in MySQL (not talked about in class or notes – you will have to search how to do it). I would like this query done 2 different ways. One that only looks at the 25 games and 1 walk on a per stint basis. That is, if they played for two different teams (two different stints) then you would count those separate. And the other query should combine all the stints they had. That is, if they played for two different teams you would add up their games and walks.
My solution is:
SELECT NAME_FIRST, NAME_LAST, SUM(strikeouts) / SUM(walks) AS KS_PER_BB
FROM mlb_master
JOIN mlb_pitching
ON mlb_master.player_id = mlb_pitching.player_id
WHERE walks >= 1 AND games >= 25
GROUP BY name_first, name_last, mlb_pitching.stint
ORDER BY KS_PER_BB DESC
LIMIT 10;
I am wondering if this solution is better for the first way my professor wants it done or the second way, if any.
This solution is appropriate for the first query because by having GROUP BY stint, each stint is considered different for each player.
For the second way, could I remove the stint column from the GROUP BY clause so that it groups the records for a particular player together, regardless of the different stints they played for?
Would this result in the sum of all their walks and strikeouts from all their stints being used to calculate the KS_PER_BB statistic, giving you the combined total for each player?

Related

how to compute percentage in mysql/sql when 2 group by conditions are present

id title count organizer
1 music 4 2
2 sports 6 2
3 music 2 3
I have a derived table with the above structure. I need to compute the percentage of the number of events of each organizer for each title. i.e. I'm expecting a result like:
organizer title percentage
2 music 40%
2 sports 60%
3 music 100%
The way I'm doing it without organizer in consideration produces the percentage aggregating all the values easily but introducing organizer messes it all up. Can anyone help me here??
Taking your derived table as the actual data (may not be optimal) you could:
select to.organizer, to.title, 100.0*to.count/o.count as percentage
from
(select organizer, sum(count) as count from derivedtable group by organizer) o
inner join
derivedtable to
on
to.organizer = o.organizer
It works by summing the data per organizer to get a total, and joining this back to the data you have so you can do the particular event-organizer count divided by the total count for that organiser
There might have been a simpler way to do it with your source data, as is you'll have to plug your query in that creates your derived table, possibly making it messy. Probably simplest to do as a CTE, but do try to include original source data and "query so far" next time you ask a question, otherwise we have to build a solution on top of some solution we know nothing about and the result might not be optimal
You can try below - using scalar subquery
DEMO
select organizer,title,count*100/(select sum(count) from tablename b where a.organizer=b.organizer)
from tablename a
OUTPUT:
organizer title percentage
2 music 40.0000
2 sports 60.0000
3 music 100.0000

how to random one result from mysql results by using one sql

I use mysql select some data for player. and the result is a list while I just want a random one.
the following sql is syntax error after limit 1
select * from tb_rank where score<=150 and score>= 50 and power>=80 and power<=120
limit 1,(select round(rand()*(select count(*) as num from tb_rank where score<=150 and score>= 50 and power>=80 and power<=120)))
50.000 people are a lot if you have them in front of you. But you are talking about crunching numbers on a computer. Here 50.000 is nothing.
Sorting would just take additional time and it is not necessary as you want a random player that has your score ±50 and your power ±20%. A random player of a sorted list is still a random player. It wouldn't make any difference.
Iterate over your playerlist, build a new list of players that have a valid score and power. Then pick a random element of that new list.
On my average laptop this takes less than 5 microsconds.

How to find the smallest difference between two columns in Mysql?

I have a table in my database which contains data for recording games between people. I wanted to have a query that would return the game which was closest between two players, ie, the smallest difference between the two scores recorded, regardless of who won. I have started with something like this as a query, but I can't quite get what I want.
SELECT recorder_score, opponent_score
from games
where recorder_id = $recorder_id
order by (recorder_score - opponent_score)
limit 1
The above obviously would only return the closest game that the person submitting the game has won, but as I mentioned, I want the closest game regardless of who wins. What will be the best way of doing this?
Use ABS in Order by to get the closest game between two players
SELECT recorder_score, opponent_score
from games
where recorder_id = $recorder_id
order by ABS(recorder_score - opponent_score)
limit 1

Query to get number of records where 0, using 2 tables

Table Structure
Table structure brief
We have 2 tables Weight and Weight_Sub, they are both identical. Our users weigh-in every 2 days and every team have a captain. So after each weigh-in team captain adds the weight according to the date in the Weight_Sub table and for that we add records in Weight table with weight 0. Once the team player accepts that score we delete them from Weight_Sub and update scores in main table i.e. Weight. E.g. If a player on 01/03/2015 was weighed 98KG we'll add there record in Weight_Sub= 98 and in Weight= 0. Once player will accept that weight then we will delete that row from Weight_Sub table and update weight in Weight table from 0 to 98.
I hope it makes sense.
Problem
We want to make a check when player accepts the score that did he missed any weigh-in. Like in the above table for 03/03/2015 in both tables the weight is 0,0 that means player missed a weigh-in. We want to get those missed weigh-in dates. The thing is we only want missed weigh-in dates which were missed after accepting the last weight, in this case on 07/03/2015.
So if you see the above image, player missed weigh-in on the 03/03/2015 but on 07/03/2015 he accepted the weight as 100KG. After that he missed 3 consecutive weighin's and then accepted on the 15/03/2015. So the query should return 3 dates i.e. 09/03/2015, 11/03/2015, 13/03/2015.
I know it can be done using PHP by running the loop and breaking when I find the accpted scores and get dates for missed weighin's but I'm looking for something for more efficient if there is.
This query will return missed records before a given date.
select w1.ID, w1.Date, w1.Weight
from `WeightTable` w1
where w1.Date < '07/03/2015' and w1.Weight = 0

Mysql SUM CASE with unique IDs only

Easiest explained through an example.
A father has children who win races.
How many of a fathers offspring have won a race and how many races in total have a fathers offspring won. (winners and wins)
I can easily figure out the total amount of wins but sometimes a child wins more than one race so to figure out winners I need only sum if the child has won, not all the times it has won.
In the below extract from a query I cannot use Distinct, so this doesn't work
SUM(CASE WHEN r.finish = '1' AND DISTINCT h.runnersid THEN 1 ELSE 0 END ) AS winners,
This also won't work
SUM(SELECT DISTINCT r.runnersid FROM runs r WHERE r.finish='1') AS winners
This works when I need to find the total amount of wins.
SUM(CASE WHEN r.finish = '1' THEN 1 ELSE 0 END ) AS wins,
Here is a sqlfiddle http://sqlfiddle.com/#!2/e9a81/1
Let's take this step by step.
You have two pieces of information you are looking for: Who has won a race, and how many races have they one.
Taking the first one, you can select a distinct runnersid where they have a first place finish:
SELECT DISTINCT runnersid
FROM runs
WHERE finish = 1;
For the second one, you can select every runnersid where they have a first place finish, count the number of rows returned, and group by runnersid to get the total wins for each:
SELECT runnersid, COUNT(*) AS numWins
FROM runs
WHERE finish = 1
GROUP BY runnersid;
The second one actually has everything you want. You don't need to do anything with that first query, but I used it to help demonstrate the thought process I take when trying to accomplish a task like this.
Here is the SQL Fiddle example.
EDIT
As you've seen, you don't really need the SUM here. Because finish represents a place in the race, you don't want to SUM that value, but you want to COUNT the number of wins.
EDIT2
An additional edit based on OPs requirements. The above does not match what OP needs, but I left this in as a reference to any future readers. What OP really needs, as I understand it now, is the number of children each father has that has run a race. I will again explain my thought process step by step.
First I wrote a simple query that pulls all of the winning father-son pairs. I was able to use GROUP BY to get the distinct winning pairs:
SELECT father, name
FROM runs
WHERE finish = 1
GROUP BY father, name;
Once I had done that, I used it is a subquery and the COUNT(*) function to get the number of winners for each father (this means I have to group by father):
SELECT father, COUNT(*) AS numWinningChildren
FROM(SELECT father, name
FROM runs
WHERE finish = 1
GROUP BY father, name) t
GROUP BY father;
If you just need the fathers with winning children, you are done. If you want to see all fathers, I would write one query to select all fathers, join it with our result set above, and replace any values where numWinningChildren is null, with 0.
I'll leave that part to you to challenge yourself a bit. Also because SQL Fiddle is down at the moment and I can't test what I was thinking, but I was able to test those above with success.
I think you want the father name along with the count of the wins by his sons.
select father, count(distinct(id)) wins
from runs where father = 'jack' and finish = 1
group by father
sqlfiddle
I am not sure if this is what you are looking for
Select user_id, sum(case when finish='1' then 1 else 0 end) as total
From table
Group by user_id