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

wen PHP项目 1

PHP项目:统计扑救次数,看哪个门将更忙?

下面给你一个完整的思路 + 可运行的 PHP 示例代码,用来统计各门将的扑救次数,并判断"谁更忙"。

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


需求分析

"谁更忙"可以量化成几个指标:

指标 含义
扑救次数 直接反映工作量
出场次数 平均每场扑救更公平
场均扑救 排除出场差异
繁忙指数 综合权重(可自定义)

数据库设计

-- 门将表
CREATE TABLE goalkeepers (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    team VARCHAR(50) NOT NULL
);
-- 比赛记录表(每场比赛每名门将一条)
CREATE TABLE saves (
    id INT PRIMARY KEY AUTO_INCREMENT,
    gk_id INT NOT NULL,
    match_id INT NOT NULL,
    save_count INT DEFAULT 0,
    played TINYINT DEFAULT 1,   -- 是否出场
    match_date DATE,
    FOREIGN KEY (gk_id) REFERENCES goalkeepers(id)
);

示例数据:

INSERT INTO goalkeepers (name, team) VALUES
('德赫亚', '曼联'), ('阿利松', '利物浦'), ('埃德森', '曼城');
INSERT INTO saves (gk_id, match_id, save_count, played, match_date) VALUES
(1, 1, 5, 1, '2024-01-01'), (1, 2, 7, 1, '2024-01-08'), (1, 3, 3, 1, '2024-01-15'),
(2, 1, 2, 1, '2024-01-01'), (2, 2, 4, 1, '2024-01-08'), (2, 3, 1, 1, '2024-01-15'),
(3, 1, 0, 1, '2024-01-01'), (3, 2, 1, 1, '2024-01-08'), (3, 3, 2, 1, '2024-01-15');

核心统计 SQL

SELECT
    g.id,
    g.name,
    g.team,
    COUNT(CASE WHEN s.played = 1 THEN 1 END) AS appearances,
    COALESCE(SUM(s.save_count), 0)            AS total_saves,
    ROUND(
        COALESCE(SUM(s.save_count), 0) /
        NULLIF(COUNT(CASE WHEN s.played = 1 THEN 1 END), 0),
        2
    ) AS avg_saves_per_match
FROM goalkeepers g
LEFT JOIN saves s ON s.gk_id = g.id
GROUP BY g.id, g.name, g.team
ORDER BY total_saves DESC;

PHP 完整实现(PDO 版)

<?php
// config.php
return [
    'dsn'  => 'mysql:host=127.0.0.1;dbname=football;charset=utf8mb4',
    'user' => 'root',
    'pass' => 'password',
];
<?php
// stats.php
$config = require 'config.php';
try {
    $pdo = new PDO($config['dsn'], $config['user'], $config['pass'], [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
} catch (PDOException $e) {
    die("数据库连接失败: " . $e->getMessage());
}
$sql = "
    SELECT
        g.id,
        g.name,
        g.team,
        COUNT(CASE WHEN s.played = 1 THEN 1 END) AS appearances,
        COALESCE(SUM(s.save_count), 0)           AS total_saves,
        ROUND(
            COALESCE(SUM(s.save_count), 0) /
            NULLIF(COUNT(CASE WHEN s.played = 1 THEN 1 END), 0),
            2
        ) AS avg_saves
    FROM goalkeepers g
    LEFT JOIN saves s ON s.gk_id = g.id
    GROUP BY g.id, g.name, g.team
    ORDER BY total_saves DESC
";
$rows = $pdo->query($sql)->fetchAll();
// 繁忙指数计算(示例权重)
foreach ($rows as &$row) {
    $row['busy_index'] = round(
        $row['total_saves'] * 1.0 + $row['avg_saves'] * 0.5,
        2
    );
}
unset($row);
// 排序得到排名
usort($rows, fn($a, $b) => $b['busy_index'] <=> $a['busy_index']);
// 输出
echo "🏆 门将繁忙度排行榜\n";
echo str_repeat('=', 60) . "\n";
printf("%-4s %-10s %-10s %-6s %-6s %-8s %-8s\n",
    '排名', '门将', '球队', '出场', '扑救', '场均扑救', '繁忙指数');
foreach ($rows as $i => $r) {
    printf("%-4d %-10s %-10s %-6d %-6d %-8.2f %-8.2f\n",
        $i + 1, $r['name'], $r['team'],
        $r['appearances'], $r['total_saves'],
        $r['avg_saves'], $r['busy_index']);
}
echo str_repeat('=', 60) . "\n";
echo "🔥 最忙门将:{$rows[0]['name']}({$rows[0]['team']})\n";

运行结果示例

🏆 门将繁忙度排行榜
============================================================
排名   门将       球队       出场   扑救   场均扑救   繁忙指数
1      德赫亚     曼联       3      15     5.00       17.50
2      阿利松     利物浦     3      7      2.33       8.17
3      埃德森     曼城       3      3      1.00       3.50
============================================================
🔥 最忙门将:德赫亚(曼联)

进阶建议

  1. 按时间段筛选:加 WHERE match_date BETWEEN ? AND ?
  2. 对手强度加权:面对强队扑救加成
  3. 零封奖励:save_count=0 且球队获胜,说明门将轻松
  4. 可视化:用 Chart.js 输出柱状图
  5. 缓存:结果放入 Redis,避免每次全表扫描
  6. 粒度细化:区分"扑救类型"(点球、单刀、常规)

要不要我帮你扩展成 按赛季 / 按联赛分别统计 的版本,或者加上 前端图表展示?

上一篇这个php项目如何点评教练组的准备工作?

下一篇当前分类已是最新一篇

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