php项目统计冲刺跑次数谁更多?

wen PHP项目 2

PHP项目:统计冲刺跑次数谁更多

下面给你一个完整的实现思路和代码示例。

php项目统计冲刺跑次数谁更多?

需求理解

假设你有一个记录跑步数据的数据表,run_records,字段包括:

  • id
  • user_id(用户)
  • run_type(跑步类型,如 'sprint' 冲刺跑 / 'jog' 慢跑)
  • distance(距离)
  • created_at

目标:统计每个用户冲刺跑的次数,并按次数降序排列,找出谁最多。


数据库表结构示例

CREATE TABLE run_records (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    run_type VARCHAR(20) NOT NULL COMMENT 'sprint=冲刺跑, jog=慢跑',
    distance DECIMAL(6,2) DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
);

核心 SQL 统计

SELECT 
    u.id,
    u.name,
    COUNT(r.id) AS sprint_count
FROM users u
LEFT JOIN run_records r 
    ON r.user_id = u.id 
    AND r.run_type = 'sprint'
GROUP BY u.id, u.name
ORDER BY sprint_count DESC;

说明:用 LEFT JOIN 保证没跑过冲刺的用户也显示(次数为 0);如果只想看有冲刺记录的人,用 INNER JOIN。


PHP 实现(PDO)

<?php
// db.php 连接配置
$host = '127.0.0.1';
$db   = 'fitness';
$user = 'root';
$pass = '';
$dsn  = "mysql:host=$host;dbname=$db;charset=utf8mb4";
try {
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
} catch (PDOException $e) {
    die('数据库连接失败: ' . $e->getMessage());
}
// 统计冲刺跑次数
$sql = "
    SELECT 
        u.id,
        u.name,
        COUNT(r.id) AS sprint_count
    FROM users u
    LEFT JOIN run_records r 
        ON r.user_id = u.id 
        AND r.run_type = 'sprint'
    GROUP BY u.id, u.name
    ORDER BY sprint_count DESC, u.name ASC
";
$stmt = $pdo->query($sql);
$ranking = $stmt->fetchAll();
// 找出第一名(可能并列)
$topCount = $ranking[0]['sprint_count'] ?? 0;
$winners  = array_filter($ranking, fn($row) => $row['sprint_count'] == $topCount);
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">冲刺跑次数排行榜</title>
    <style>
        table { border-collapse: collapse; width: 400px; }
        th, td { border: 1px solid #ccc; padding: 8px 12px; text-align: center; }
        th { background: #f5f5f5; }
        .top { background: #fff8d6; font-weight: bold; }
    </style>
</head>
<body>
    <h2>冲刺跑次数排行榜</h2>
    <table>
        <thead>
            <tr><th>排名</th><th>用户</th><th>冲刺次数</th></tr>
        </thead>
        <tbody>
        <?php $rank = 1; foreach ($ranking as $row): ?>
            <tr class="<?= $row['sprint_count'] == $topCount && $topCount > 0 ? 'top' : '' ?>">
                <td><?= $rank++ ?></td>
                <td><?= htmlspecialchars($row['name']) ?></td>
                <td><?= (int)$row['sprint_count'] ?></td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    <p>
        <strong>冲刺跑次数最多的用户:</strong>
        <?php 
            if ($topCount == 0) {
                echo '暂无冲刺记录';
            } else {
                echo implode('、', array_column($winners, 'name')) 
                   . ",共 {$topCount} 次冲刺跑";
            }
        ?>
    </p>
</body>
</html>

进一步优化建议

  1. 按时间段统计(如本周/本月):

    ... AND r.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
  2. 按距离阈值判定冲刺(如果没有 run_type,可根据配速或距离判断):

    COUNT(CASE WHEN r.distance >= 0.1 AND r.distance <= 0.5 THEN 1 END) AS sprint_count
  3. 大数据量时给 (user_id, run_type) 加联合索引:

    CREATE INDEX idx_user_type ON run_records(user_id, run_type);
  4. 输出 JSON 接口(给前端调用):

    header('Content-Type: application/json');
    echo json_encode([
        'ranking' => $ranking,
        'top_count' => $topCount,
        'winners' => array_values($winners),
    ], JSON_UNESCAPED_UNICODE);

如果你没有 run_type 字段

如果你的原始数据只有配速(pace,秒/公里)或时间距离,可以按业务规则定义"冲刺":配速快于 4 分/公里:

SELECT u.name, COUNT(r.id) AS sprint_count
FROM users u
LEFT JOIN run_records r 
    ON r.user_id = u.id AND r.pace <= 240   -- 4分钟=240秒/公里
GROUP BY u.id, u.name
ORDER BY sprint_count DESC;

需要我根据你的真实表结构(字段名、类型判定规则)改成可直接运行的代码吗?把你现有的表结构或相关代码贴出来,我可以帮你精确适配。

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