jockey_stats
Analyze jockey performance statistics including win rates, place percentages, and ride counts. Filter results by venue, distance, or time period to evaluate racing effectiveness.
Instructions
騎手の成績を分析
騎手名を指定して、勝率・複勝率・騎乗数などを調べられます。 競馬場や距離でのフィルタリングも可能です。
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| jockey_name | Yes | ||
| venue | No | ||
| year_from | No | ||
| distance | No |
Implementation Reference
- src/jvlink_mcp_server/server.py:485-501 (handler)The tool 'jockey_stats' is registered here, which calls '_get_jockey_stats' from high_level_api.py.
@mcp.tool(name="jockey_stats") def analyze_jockey_stats( jockey_name: str, venue: Optional[str] = None, year_from: Optional[str] = None, distance: Optional[int] = None ) -> dict: """騎手の成績を分析 騎手名を指定して、勝率・複勝率・騎乗数などを調べられます。 競馬場や距離でのフィルタリングも可能です。 """ with DatabaseConnection() as db: return _get_jockey_stats( db, jockey_name=jockey_name, venue=venue, year_from=year_from, distance=distance ) - The internal implementation '_jockey_stats_impl' executes the SQL query for jockey statistics.
def _jockey_stats_impl( db_connection, jockey_name: str, venue: Optional[str] = None, year_from: Optional[str] = None, distance: Optional[int] = None, source: str = 'jra' ) -> Dict[str, Any]: """騎手成績の共通実装(JRA/NAR兼用)""" tables = _SOURCE_TABLES[source] conditions = [] query_params: List = [] condition_desc = [f"騎手名: {jockey_name}(部分一致)"] if source == 'nar': condition_desc.append("NAR地方競馬") conditions.append("s.KisyuRyakusyo LIKE ?") query_params.append('%' + jockey_name + '%') conditions.append("s.KakuteiJyuni IS NOT NULL") conditions.append("s.KakuteiJyuni > 0") if venue: venue_code = _resolve_venue(venue, source) conditions.append("s.JyoCD = ?") query_params.append(venue_code) condition_desc.append(f"{venue}競馬場") if year_from: year_val = _validate_year(year_from) conditions.append("s.Year >= ?") query_params.append(year_val) condition_desc.append(f"{year_val}年以降") if distance: conditions.append("r.Kyori = ?") query_params.append(distance) condition_desc.append(f"{distance}m") where_clause = " AND ".join(conditions) if distance: query = f""" SELECT s.KisyuRyakusyo as jockey_name, COUNT(*) as total_rides, SUM(CASE WHEN s.KakuteiJyuni = 1 THEN 1 ELSE 0 END) as wins, SUM(CASE WHEN s.KakuteiJyuni IN (1, 2) THEN 1 ELSE 0 END) as places_2, SUM(CASE WHEN s.KakuteiJyuni IN (1, 2, 3) THEN 1 ELSE 0 END) as places_3 FROM {tables['se']} s JOIN {tables['ra']} r ON s.Year = r.Year AND s.MonthDay = r.MonthDay AND s.JyoCD = r.JyoCD AND s.Kaiji = r.Kaiji AND s.Nichiji = r.Nichiji AND s.RaceNum = r.RaceNum WHERE {where_clause} GROUP BY s.KisyuRyakusyo """ else: query = f""" SELECT s.KisyuRyakusyo as jockey_name, COUNT(*) as total_rides, SUM(CASE WHEN s.KakuteiJyuni = 1 THEN 1 ELSE 0 END) as wins, SUM(CASE WHEN s.KakuteiJyuni IN (1, 2) THEN 1 ELSE 0 END) as places_2, SUM(CASE WHEN s.KakuteiJyuni IN (1, 2, 3) THEN 1 ELSE 0 END) as places_3 FROM {tables['se']} s WHERE {where_clause} GROUP BY s.KisyuRyakusyo """ df = db_connection.execute_safe_query(query, params=tuple(query_params)) if df.empty: return { 'jockey_name': jockey_name, 'total_rides': 0, 'wins': 0, 'places_2': 0, 'places_3': 0, 'win_rate': 0.0, 'place_rate_2': 0.0, 'place_rate_3': 0.0, 'conditions': ', '.join(condition_desc), 'query': query } total_rides = int(df['total_rides'].sum()) wins = int(df['wins'].sum()) places_2 = int(df['places_2'].sum()) places_3 = int(df['places_3'].sum()) matched_jockey = df.loc[df['total_rides'].idxmax(), 'jockey_name'] return { 'jockey_name': matched_jockey, 'total_rides': total_rides, 'wins': wins, 'places_2': places_2, 'places_3': places_3, 'win_rate': (wins / total_rides * 100) if total_rides > 0 else 0.0, 'place_rate_2': (places_2 / total_rides * 100) if total_rides > 0 else 0.0, 'place_rate_3': (places_3 / total_rides * 100) if total_rides > 0 else 0.0, 'conditions': ', '.join(condition_desc), 'matched_jockeys': df['jockey_name'].tolist(), 'query': query }