PHP 项目统计"转身过人"次数
你说的应该是 篮球相关的"转身过人"(Spin Move) 统计吧?我来给你一个完整的 PHP 实现方案。

需求分析
统计每个球员的"转身过人"动作次数,找出次数最多的人。
数据库设计
-- 球员表
CREATE TABLE players (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
team VARCHAR(50)
);
-- 动作记录表
CREATE TABLE actions (
id INT PRIMARY KEY AUTO_INCREMENT,
player_id INT NOT NULL,
action_type VARCHAR(50) NOT NULL, -- 如: 'spin_move'
match_id INT,
happened_at DATETIME,
FOREIGN KEY (player_id) REFERENCES players(id)
);
-- 插入示例数据
INSERT INTO players (name, team) VALUES
('库里', '勇士'), ('欧文', '独行侠'), ('东契奇', '独行侠'), ('哈登', '快船');
INSERT INTO actions (player_id, action_type, match_id) VALUES
(1, 'spin_move', 1), (1, 'spin_move', 1), (1, 'crossover', 1),
(2, 'spin_move', 1), (2, 'spin_move', 1), (2, 'spin_move', 1), (2, 'spin_move', 1),
(3, 'spin_move', 2), (3, 'spin_move', 2), (3, 'spin_move', 2),
(4, 'spin_move', 2);
核心统计代码
方式1:SQL 聚合(推荐,效率最高)
<?php
$pdo = new PDO('mysql:host=localhost;dbname=nba;charset=utf8mb4', 'root', 'password');
$sql = "SELECT p.id, p.name, p.team, COUNT(a.id) AS spin_count
FROM players p
LEFT JOIN actions a
ON a.player_id = p.id
AND a.action_type = 'spin_move'
GROUP BY p.id, p.name, p.team
ORDER BY spin_count DESC";
$stmt = $pdo->query($sql);
$ranking = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "===== 转身过人次数排行榜 =====\n";
foreach ($ranking as $i => $row) {
echo sprintf("%d. %s(%s) - %d 次\n",
$i + 1, $row['name'], $row['team'], $row['spin_count']);
}
// 谁最多?
if (!empty($ranking)) {
$top = $ranking[0];
echo "\n🏆 转身过人最多:{$top['name']},共 {$top['spin_count']} 次\n";
}
方式2:纯 PHP 数组统计
<?php
$records = [
['player' => '欧文', 'action' => 'spin_move'],
['player' => '库里', 'action' => 'spin_move'],
['player' => '欧文', 'action' => 'spin_move'],
['player' => '东契奇', 'action' => 'spin_move'],
['player' => '库里', 'action' => 'crossover'],
['player' => '欧文', 'action' => 'spin_move'],
['player' => '东契奇', 'action' => 'spin_move'],
];
$counter = [];
foreach ($records as $r) {
if ($r['action'] === 'spin_move') {
$counter[$r['player']] = ($counter[$r['player']] ?? 0) + 1;
}
}
arsort($counter); // 降序
print_r($counter);
$max = key($counter);
echo "转身过人最多:{$max},{$counter[$max]} 次\n";
进阶:按比赛/时间段统计
// 某场比赛的转身过人统计
$sql = "SELECT p.name, COUNT(*) AS cnt
FROM actions a
JOIN players p ON p.id = a.player_id
WHERE a.action_type = 'spin_move'
AND a.match_id = :match_id
GROUP BY p.id, p.name
ORDER BY cnt DESC
LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute([':match_id' => 1]);
$mvp = $stmt->fetch(PDO::FETCH_ASSOC);
echo "本场转身过人王:{$mvp['name']} ({$mvp['cnt']} 次)";
性能优化建议
| 场景 | 优化方案 |
|---|---|
| 数据量大 | 给 action_type、player_id 加索引 |
| 高并发查询 | 用 Redis 缓存排行榜 |
| 实时统计 | 写入时同步更新 Redis Sorted Set (ZINCRBY) |
| 历史数据多 | 按 match_id 分表或分区 |
Redis 实时排行示例:
$redis->zIncrBy('spin_move_rank', 1, $playerName);
$top = $redis->zRevRange('spin_move_rank', 0, 4, true); // 前5名
如果你说的不是篮球,而是其他场景的"转身过人"(比如游戏角色、舞蹈动作等),告诉我具体场景,我可以调整表结构,需要我把完整项目(含 API + 前端展示)也写出来吗?