PHP项目:统计冲刺跑次数谁更多?
这是一个常见的"数据统计+比较"需求,下面给你一个完整的实现思路和代码示例。

需求分析
假设场景:有一群运动员,每人可以多次记录"冲刺跑"成绩,需要统计谁的冲刺跑次数最多。
需要的数据结构:
- 运动员(用户)
- 每次冲刺跑记录(属于某个运动员)
数据库设计
-- 用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL
);
-- 冲刺跑记录表
CREATE TABLE sprint_records (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
distance DECIMAL(5,2) COMMENT '距离(米)',
duration DECIMAL(5,2) COMMENT '用时(秒)',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
核心统计代码(PHP + MySQL)
方法1:用 SQL 直接分组统计(推荐)
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'root', '123456');
// 统计每人冲刺跑次数,按次数降序
$sql = "
SELECT u.id, u.name, COUNT(s.id) AS sprint_count
FROM users u
LEFT JOIN sprint_records s ON u.id = s.user_id
GROUP BY u.id, u.name
ORDER BY sprint_count DESC
";
$stmt = $pdo->query($sql);
$ranking = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 输出结果
echo "冲刺跑次数排行榜:\n";
foreach ($ranking as $index => $row) {
echo ($index + 1) . ". {$row['name']} —— {$row['sprint_count']} 次\n";
}
// 找出谁最多(可能并列)
$maxCount = $ranking[0]['sprint_count'] ?? 0;
$winners = array_filter($ranking, fn($r) => $r['sprint_count'] == $maxCount);
if (count($winners) === 1) {
$winner = reset($winners);
echo "\n🏆 冲刺跑次数最多的是:{$winner['name']},共 {$winner['sprint_count']} 次\n";
} else {
$names = implode('、', array_column($winners, 'name'));
echo "\n🏆 并列第一:{$names},各 {$maxCount} 次\n";
}
方法2:用 PHP 数组统计(数据量小时用)
<?php
// 假设从数据库取出的原始记录
$records = [
['user_id' => 1, 'name' => '张三'],
['user_id' => 2, 'name' => '李四'],
['user_id' => 1, 'name' => '张三'],
['user_id' => 3, 'name' => '王五'],
['user_id' => 1, 'name' => '张三'],
['user_id' => 2, 'name' => '李四'],
];
// 统计次数
$counts = [];
foreach ($records as $r) {
$uid = $r['user_id'];
if (!isset($counts[$uid])) {
$counts[$uid] = ['name' => $r['name'], 'count' => 0];
}
$counts[$uid]['count']++;
}
// 按次数降序
uasort($counts, fn($a, $b) => $b['count'] <=> $a['count']);
// 输出
foreach ($counts as $item) {
echo "{$item['name']}:{$item['count']} 次\n";
}
只想要"谁最多"
如果只关心第一名,SQL 更简洁:
$sql = "
SELECT u.name, COUNT(s.id) AS cnt
FROM users u
JOIN sprint_records s ON u.id = s.user_id
GROUP BY u.id, u.name
ORDER BY cnt DESC
LIMIT 1
";
$top = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
echo "冲刺跑最多:{$top['name']}({$top['cnt']} 次)";
几个实际注意点
| 场景 | 建议 |
|---|---|
| 数据量大 | 给 sprint_records.user_id 加索引 |
| 需要按时间段统计 | SQL 加 WHERE s.created_at BETWEEN ? AND ? |
| 并列第一 | 用 LIMIT 1 会漏掉,改用上面的 array_filter 方案 |
| 排除0次用户 | 把 LEFT JOIN 改成 INNER JOIN |
| 性能优化 | 频繁统计可加缓存表或 Redis |
进阶:按时间段统计
$sql = "
SELECT u.name, COUNT(s.id) AS cnt
FROM users u
JOIN sprint_records s ON u.id = s.user_id
WHERE s.created_at >= :start AND s.created_at < :end
GROUP BY u.id, u.name
ORDER BY cnt DESC
";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':start' => '2024-01-01 00:00:00',
':end' => '2024-02-01 00:00:00',
]);
如果你能告诉我具体的业务场景(体育训练打卡?游戏排行榜?学校体测?)以及已有的表结构,我可以给你更贴合的实现代码。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播