php项目统计扑救次数门将谁更忙?

wen PHP项目 5

本文目录导读:

php项目统计扑救次数门将谁更忙?

  1. 方案一:基础版(根据扑救次数排序)
  2. 方案二:进阶版(综合活跃度指数)
  3. 特别提醒:如何避免“统计陷阱”?
  4. 如果项目是Laravel或ThinkPHP框架

在PHP项目中统计“门将谁更忙”,不能只看扑救次数这一个维度,因为扑救次数多往往意味着后防线漏洞大(或对手射门多),而门将的“忙” 通常包含处理球权(触球)、出击、传球等非扑救动作。

针对你的需求,我提供两种PHP实现方案:基础版(只看扑救次数)进阶版(综合活跃度指数)

基础版(根据扑救次数排序)

这适合只看单一指标的简单统计,假设你有goalkeepers表和matches表(或直接一个goalkeeper_stats统计表)。

数据库结构示例

-- 球员表
CREATE TABLE players (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);
-- 单场比赛门将数据表
CREATE TABLE match_goalkeeper_stats (
    id INT PRIMARY KEY AUTO_INCREMENT,
    player_id INT,
    match_id INT,
    saves INT DEFAULT 0,          -- 扑救次数
    goals_conceded INT DEFAULT 0, -- 失球数
    touches INT DEFAULT 0,        -- 触球次数(进阶用)
    clearances INT DEFAULT 0,     -- 出击解围次数(进阶用)
    passes INT DEFAULT 0,         -- 成功传球次数(进阶用)
    FOREIGN KEY (player_id) REFERENCES players(id)
);

PHP统计代码(MySQLi 或 PDO 示例)

<?php
// 假设已连接数据库 $pdo
function getBusiestGoalkeeperBySaves(PDO $pdo, string $season = '2024') {
    $sql = "
        SELECT 
            p.name AS goalkeeper_name,
            SUM(mgs.saves) AS total_saves,
            COUNT(DISTINCT mgs.match_id) AS matches_played
        FROM match_goalkeeper_stats mgs
        INNER JOIN players p ON p.id = mgs.player_id
        INNER JOIN matches m ON m.id = mgs.match_id
        WHERE m.season = :season
        GROUP BY p.id, p.name
        ORDER BY total_saves DESC
        LIMIT 10
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([':season' => $season]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 使用示例
$busiest = getBusiestGoalkeeperBySaves($pdo);
foreach ($busiest as $gk) {
    echo "{$gk['goalkeeper_name']}: 扑救 {$gk['total_saves']} 次 (出场 {$gk['matches_played']} 场)\n";
}
?>

进阶版(综合活跃度指数)

如果项目需要判断谁在场上“更忙碌”,单看扑救不够,因为强队门将可能全场触球5次,弱队门将扑救10次,更科学的指标是 “忙碌度指数”,即门将参与比赛的比例。

公式建议: 假设统计所有门将的总触球次数扑救次数成功传球次数

<?php
function getBusiestGoalkeeperComposite(PDO $pdo, string $season = '2024') {
    $sql = "
        SELECT 
            p.name AS goalkeeper_name,
            SUM(mgs.saves) AS total_saves,
            SUM(mgs.touches) AS total_touches,
            SUM(mgs.passes) AS total_passes,
            SUM(mgs.clearances) AS total_clearances,
            COUNT(DISTINCT mgs.match_id) AS matches_played,
            -- 忙碌度公式:权重可根据联赛风格调整
            ROUND(
                (SUM(mgs.saves) * 3 + SUM(mgs.touches) * 1 + SUM(mgs.clearances) * 2 + SUM(mgs.passes) * 0.5) / COUNT(DISTINCT mgs.match_id),
                2
            ) AS busy_index
        FROM match_goalkeeper_stats mgs
        INNER JOIN players p ON p.id = mgs.player_id
        INNER JOIN matches m ON m.id = mgs.match_id
        WHERE m.season = :season
        GROUP BY p.id, p.name
        ORDER BY busy_index DESC
        LIMIT 10
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([':season' => $season]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 示例输出
$result = getBusiestGoalkeeperComposite($pdo);
echo "门将忙碌度排行:\n";
foreach ($result as $gk) {
    echo "{$gk['goalkeeper_name']} - 指数: {$gk['busy_index']} (扑救: {$gk['total_saves']}, 触球: {$gk['total_touches']})\n";
}
?>

特别提醒:如何避免“统计陷阱”?

如果你发现某门将扑救次数异常高(比如20次),可能是队友太差导致,更专业的比较方式是看扑救成功率失球率

补充SQL示例(按扑救成功率排名)

$sql = "
    SELECT 
        p.name,
        SUM(mgs.saves) AS saves,
        SUM(mgs.goals_conceded) AS conceded,
        ROUND(SUM(mgs.saves) / NULLIF(SUM(mgs.saves) + SUM(mgs.goals_conceded), 0) * 100, 2) AS save_percentage
    FROM match_goalkeeper_stats mgs
    JOIN players p ON p.id = mgs.player_id
    GROUP BY p.id
    ORDER BY save_percentage DESC
";

如果项目是Laravel或ThinkPHP框架

如果你用的是Laravel模型,可以用查询构造器直接实现:

// Laravel版本
$busiest = Player::query()
    ->select('players.name')
    ->selectRaw('SUM(stats.saves) as total_saves')
    ->selectRaw('SUM(stats.touches) as total_touches')
    ->selectRaw('ROUND((SUM(stats.saves) * 3 + SUM(stats.touches)) / COUNT(DISTINCT stats.match_id), 2) as busy_index')
    ->join('match_goalkeeper_stats as stats', 'players.id', '=', 'stats.player_id')
    ->join('matches as m', 'm.id', '=', 'stats.match_id')
    ->where('m.season', $season)
    ->groupBy('players.id')
    ->orderByDesc('busy_index')
    ->get();

如果只求简单,用SUM(saves)排序;如果做专业足球数据分析,建议使用复合指数(结合触球、出击、传球),这样才真正反映“谁更忙”,你可以根据项目数据字段,直接替换上述SQL中的列名即可。

抱歉,评论功能暂时关闭!