本文目录导读:

在PHP项目中统计“定位球得分占比”,核心是先定义清楚“定位球”的范围(通常指:角球、任意球(直接/间接)、点球、界外球或战术配合后的进球),然后再通过SQL查询或数组统计来计算。
以下我给你一套从SQL查询到PHP计算的完整解决方案,你可以直接套用。
第一步:定义数据表结构(假设)
假设你有一个 goals 表,结构如下(这是最常用的设计):
-- 进球记录表
CREATE TABLE goals (
id INT PRIMARY KEY AUTO_INCREMENT,
match_id INT NOT NULL, -- 比赛ID
player_id INT, -- 进球球员ID
goal_type ENUM('open_play', 'corner', 'free_kick', 'penalty', 'own_goal') NOT NULL,
-- open_play = 运动战, corner = 角球, free_kick = 任意球, penalty = 点球, own_goal = 乌龙球
minute INT, -- 进球分钟
created_at TIMESTAMP
);
第二步:PHP后端核心代码
这里给你两个版本的统计逻辑,一个用原生的MySQLi,一个用PDO(推荐)。
使用原生 SQL 一次性查询(最高效)
<?php
// 假设你已经连接了数据库 $conn (MySQLi)
// 1. 统计所有非乌龙球的进球总数
$sqlTotal = "SELECT COUNT(*) AS total
FROM goals
WHERE goal_type != 'own_goal'"; // 通常乌龙球不计入进攻统计
$resultTotal = $conn->query($sqlTotal);
$totalGoals = $resultTotal->fetch_assoc()['total'];
// 2. 统计定位球进球数
// 定位球 = 角球 + 任意球 + 点球
$sqlSetPiece = "SELECT
SUM(CASE WHEN goal_type IN ('corner', 'free_kick', 'penalty') THEN 1 ELSE 0 END) AS set_piece_goals,
SUM(CASE WHEN goal_type = 'open_play' THEN 1 ELSE 0 END) AS open_play_goals,
SUM(CASE WHEN goal_type = 'corner' THEN 1 ELSE 0 END) AS corner_goals,
SUM(CASE WHEN goal_type = 'free_kick' THEN 1 ELSE 0 END) AS free_kick_goals,
SUM(CASE WHEN goal_type = 'penalty' THEN 1 ELSE 0 END) AS penalty_goals
FROM goals
WHERE goal_type != 'own_goal'";
$resultSetPiece = $conn->query($sqlSetPiece);
$data = $resultSetPiece->fetch_assoc();
// 3. 计算占比(防止除以零)
$setPieceGoals = $data['set_piece_goals'];
$percentage = ($totalGoals > 0) ? round(($setPieceGoals / $totalGoals) * 100, 2) : 0;
// 4. 输出结果
echo "总进球数: " . $totalGoals . "<br>";
echo "定位球进球数: " . $setPieceGoals . "<br>";
echo "定位球得分占比: " . $percentage . "% <br>";
echo "<hr>";
echo "<br>";
echo "角球占比: " . round(($data['corner_goals'] / max($totalGoals,1)) * 100, 2) . "%<br>";
echo "任意球占比: " . round(($data['free_kick_goals'] / max($totalGoals,1)) * 100, 2) . "%<br>";
echo "点球占比: " . round(($data['penalty_goals'] / max($totalGoals,1)) * 100, 2) . "%<br>";
$conn->close();
?>
PDO + 预处理(适合框架或更安全的项目)
<?php
// 假设 $pdo 是 PDO 连接实例
// 总进球数(排除乌龙)
$stmt = $pdo->query("SELECT COUNT(*) FROM goals WHERE goal_type != 'own_goal'");
$totalGoals = $stmt->fetchColumn();
// 定位球分类统计
$stmt = $pdo->query("
SELECT
COUNT(CASE WHEN goal_type IN ('corner', 'free_kick', 'penalty') THEN 1 END) AS set_piece,
COUNT(CASE WHEN goal_type = 'corner' THEN 1 END) AS corner,
COUNT(CASE WHEN goal_type = 'free_kick' THEN 1 END) AS free_kick,
COUNT(CASE WHEN goal_type = 'penalty' THEN 1 END) AS penalty
FROM goals
WHERE goal_type != 'own_goal'
");
$stats = $stmt->fetch(PDO::FETCH_ASSOC);
// 计算比例
$percentage = $totalGoals > 0 ? round(($stats['set_piece'] / $totalGoals) * 100, 1) : 0;
echo "定位球得分占比: {$percentage}%";
?>
第三步:如果你只统计【某一场特定比赛】或【某个赛季】
只需在上述SQL的 WHERE 子句后添加筛选条件:
-- 筛选某场比赛 WHERE match_id = 123 AND goal_type != 'own_goal' -- 筛选某个赛季(假设你有赛季关联) WHERE match_id IN (SELECT id FROM matches WHERE season_id = 2024) AND goal_type != 'own_goal'
第四步:如果是纯PHP数组(没有数据库)
如果你是从第三方API获取的数据,数据在PHP数组里,可以这样算:
$goals = [
['type' => 'open_play', 'player' => 'A'],
['type' => 'corner', 'player' => 'B'],
['type' => 'penalty', 'player' => 'C'],
['type' => 'free_kick', 'player' => 'D'],
// ...其他数据
];
$total = 0;
$setPiece = 0;
foreach ($goals as $goal) {
if ($goal['type'] == 'own_goal') continue; // 跳过乌龙球
$total++;
if (in_array($goal['type'], ['corner', 'free_kick', 'penalty'])) {
$setPiece++;
}
}
$percent = $total > 0 ? round($setPiece / $total * 100, 2) : 0;
echo "定位球占比: {$percent}%";
最后提醒你一下(关于业务逻辑)
常见的处理差异点:
- 乌龙球:通常不计入球队的定位球统计,但如果你想把乌龙球也算作“对方定位球得分”(通常不这么干),请自行调整上面的
WHERE条件。 - 点球:有些统计口径会把点球算作定位球,有些则不算(因为点球主要是个人技术对抗门将),默认上面的代码是算的,如果你不想算,把
penalty从IN子句里去掉即可。 - 任意球间接配合:如果进球前经过1次传球配合,但第一脚是任意球,通常依然算作定位球,这取决于你的
goal_type字段的录入规则。
如果想把这个统计做成一个函数或类(GoalStatistics::getSetPiecePercentage()),或者需要适配 Laravel / ThinkPHP 框架的代码写法,告诉我你用的框架,我可以再给你写框架版本。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播