Определение лет новичка в базе данных Lahman

#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

Я нашел другого парня, который делал что-то похожее на то, что делаете вы (включая вычисление того, кто является новичком). Вот его сайт (с кодом):

http://baseballsimulator.com/blog/category/database/

Комментарии:

1. Единственное, что вызывает у меня проблемы, это то, что таблицы отбивающих и подающих приведены с разбивкой по сезонам моих игроков, поэтому каждая запись относится только к одному сезону для каждого игрока. К сожалению, право игроков на участие в качестве новичков может распространяться на два или более сезонов (т. е. Игрок X делает 40 подач в одном сезоне, а остальные 10 — в следующем сезоне). Есть ли способ просмотреть все записи игроков в таблице питчинга, чтобы узнать, в каком конкретном сезоне они достигли и / или превысили минимальное значение?