#mysql
#mysql
Вопрос:
Я использую версию MySQL базы данных бейсбола Lahman, и у меня возникли проблемы при попытке определить год, когда игрок потерял статус новичка. Правила для игрока MLB, теряющего статус новичка, следующие:
Игрок считается новичком, если только в течение предыдущего сезона или сезонов он (а) не провел более 130 атак или 50 подач в Высшей лиге; или (б) не провел более 45 дней в активном составе клуба или клубов Высшей лиги в течение периода ограничения в 25 игроков (исключая время на военной службе и время в списке инвалидов).
Есть ли запрос, который можно выполнить для выполнения этого для отбивающих и питчеров, или это что-то, что можно было бы выполнить программно?
Ответ №1:
Используя базу данных Lahman, вы можете определить новичков по количеству подач (> 130) и количеству подач (> 50), однако время обслуживания в составе 25 человек (за исключением сентября) ничего не указывает.
Вам понадобятся ретрошиферы {http://www.retrosheet.org/game.htm} данные для этого.
Приведенные ниже запросы выдадут вам ВСЕХ новичков по количеству подач, однако новички со сроком службы будут исключением. Таких всего несколько, поскольку команды не склонны держать новичков в составе MLB и не играть с ними. Теряют время разработки (не играют) и ускоряют время обслуживания, чтобы потерять контролируемые годы. Итак, если вас это устраивает, подойдут эти таблицы.
Вы можете использовать это как таблицу внешних ссылок с отбивающими или питчерами, чтобы выделить год их новичка. Или вы могли бы добавить дополнительный столбец для отбивающих и питчеров с различием RookieYr (не советую этого делать, так как если вы хотите добавить новые сезоны в свою базу данных Lahman — меньше настроек требуется).
/************************************ Create MLB Rookie Xref Table **********************************************
-- Sort Out Batters who accumulate 130 AB
-- Sort Out Pitchers who accumulate 50 IP
-- Define Rookie Year, Drop off years previous and years after
-- Can be updated Annually using "player ID not in (select distinct playerID from Xref_RookieYr)
-- Using the Sean Lahman Database
-- Authored By Paul DeVos {www.linkedin.com/in/devosp/}
*****************************************************************************************************************/
/****** Query uses T-SQL, Query ran in MS SQL 2012 - you may need to tweek for other platorms or versions. ******/
--Step 1 - Run this for hitter accumulated ABs and when Rookie Year (130 Career At Bats)
Select
concat(m.nameFirst, ' ', m.nameLast) as Name,
b.PlayerID,
b.yearID,
m.debut,
sum(b.ab) over (partition by b.playerID order by b.playerID, b.yearID) as CumulativeAB,
null as CumulativeIP, -- Place Holder for Rookie Pitchers Insert
case when sum(b.ab) over (partition by b.playerID order by b.playerID, b.yearID) >= 130 then b.yearID end as RookieYR
into #temp_rookie_year
from
[master] m
inner join Batting b
on m.playerID=b.playerID
-- Selects Position Players
where b.playerID not in (select distinct f.playerID from Fielding f where f.pos = 'P')
--Step 2 - Run this to get accumulated IP and Rookie Year (50 Career IP)
Insert into #temp_rookie_year
(
Name, PlayerID, YearID, Debut, CumulativeAB, CumulativeIP, RookieYR
)
Select
concat(m.nameFirst, ' ', m.nameLast) as Name,
p.PlayerID,
p.yearID,
m.debut,
null as CumulativeAB,
sum(p.IPouts) over (partition by p.playerID order by p.playerID, p.yearID) as CumulativeIP,
case when sum(p.IPouts) over (partition by p.playerID order by p.playerID, p.yearID) >= 150 then p.yearID end as RookieYR
from [master] m
inner join pitching p
on m.playerID=p.playerID
--Chooses Pitchers
where p.playerID in (select distinct f.playerID from Fielding f where f.pos = 'P')
--Step 3 Run this - sorts out the rookie year into Rookie Xref Table
select Name, PlayerID, min(RookieYr) as RookieYear
into #Xref_RookieYr
from #temp_rookie_year
--where name = 'Hank Aaron'
group by Name, PlayerID
order by RookieYear desc
--Step 4 - run IF you want to remove players who never lost rookie status (cup of cofee players, etc - anyone under 130 AB or 50 IP)
select * from #Xref_RookieYr
order by playerID
Delete from #Xref_RookieYr where RookieYear is null
select * from #Xref_RookieYr
order by playerID
/*****************************************************************************************************************
You can change drop the "#" in front of the table (and name it whatever you want) when you want a permanent table.
If you leave it, it'll drop off when you close the program. e.g. Xref_Rookie_2013
*****************************************************************************************************************/
Ответ №2:
Это можно сделать в SQL. То, как это делается, будет основано на том, какой способ является наиболее оптимальным для этого. Скорее всего, это можно было бы сделать с помощью одного запроса, подобного so (псевдокод):
SELECT Master.*
FROM Master
LEFT JOIN Batting ON Master.player_id = Batting.player_id
LEFT JOIN Pitching ON Master.player_id = Pitching.player_id
WHERE Batting.AB > 130 OR Pitching.IPOuts > (50 x 3)
OR Master.DaysActive > 45
Последняя часть инструкции WHERE немного сомнительна, потому что я не нахожу ничего подобного в данных от вашего поставщика базы данных. Я вижу активные игры, но это не одно и то же. Таблица появлений может приблизить вас, но это все, что вы можете сделать.
Вот данные, на которых я основывал свой псевдокод:
http://baseball1.com/files/database/readme58.txt
Я нашел другого парня, который делал что-то похожее на то, что делаете вы (включая вычисление того, кто является новичком). Вот его сайт (с кодом):
Комментарии:
1. Единственное, что вызывает у меня проблемы, это то, что таблицы отбивающих и подающих приведены с разбивкой по сезонам моих игроков, поэтому каждая запись относится только к одному сезону для каждого игрока. К сожалению, право игроков на участие в качестве новичков может распространяться на два или более сезонов (т. е. Игрок X делает 40 подач в одном сезоне, а остальные 10 — в следующем сезоне). Есть ли способ просмотреть все записи игроков в таблице питчинга, чтобы узнать, в каком конкретном сезоне они достигли и / или превысили минимальное значение?