php项目统计红黄牌数量哪队更多?

wen PHP项目 2

PHP项目统计红黄牌数量哪队更多

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

php项目统计红黄牌数量哪队更多?

数据表结构设计

CREATE TABLE match_cards (
    id INT AUTO_INCREMENT PRIMARY KEY,
    match_id INT NOT NULL COMMENT '比赛ID',
    team_id INT NOT NULL COMMENT '球队ID',
    team_name VARCHAR(50) NOT NULL COMMENT '球队名称',
    card_type ENUM('yellow','red') NOT NULL COMMENT '牌类型',
    player_name VARCHAR(50) COMMENT '球员名',
    minute INT COMMENT '发生分钟',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

核心统计逻辑(PDO 示例)

<?php
// db.php 数据库连接
$pdo = new PDO('mysql:host=localhost;dbname=football;charset=utf8mb4', 'root', 'password', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
/**
 * 统计指定比赛(或全部比赛)各队红黄牌数量
 * @param PDO $pdo
 * @param int|null $matchId 传 null 表示统计全部
 * @return array
 */
function getCardStats(PDO $pdo, ?int $matchId = null): array
{
    $sql = "
        SELECT
            team_id,
            team_name,
            SUM(card_type = 'yellow') AS yellow_count,
            SUM(card_type = 'red')    AS red_count,
            COUNT(*)                  AS total_count,
            -- 加权分:黄牌1分,红牌2分(可按业务调整)
            SUM(card_type = 'yellow') * 1 + SUM(card_type = 'red') * 2 AS score
        FROM match_cards
    ";
    $params = [];
    if ($matchId !== null) {
        $sql .= " WHERE match_id = :match_id";
        $params[':match_id'] = $matchId;
    }
    $sql .= " GROUP BY team_id, team_name ORDER BY score DESC, red_count DESC";
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    return $stmt->fetchAll();
}
/**
 * 判断哪队红黄牌更多
 * @param array $stats getCardStats 的返回
 * @return array
 */
function compareCards(array $stats): array
{
    if (count($stats) < 2) {
        return ['winner' => null, 'message' => '数据不足,无法比较'];
    }
    $first  = $stats[0];
    $second = $stats[1];
    // 完全一样的情况
    if ($first['score'] == $second['score']
        && $first['yellow_count'] == $second['yellow_count']
        && $first['red_count'] == $second['red_count']) {
        return [
            'winner'  => null,
            'message' => "两队牌数相同:{$first['team_name']} 与 {$second['team_name']}"
        ];
    }
    return [
        'winner'  => $first['team_name'],
        'message' => sprintf(
            '%s 牌更多(黄牌%d张/红牌%d张,加权%d分),比 %s 多 %d 分',
            $first['team_name'],
            $first['yellow_count'],
            $first['red_count'],
            $first['score'],
            $second['team_name'],
            $first['score'] - $second['score']
        ),
        'detail'  => $stats,
    ];
}
// ====== 使用示例 ======
$matchId = 1001; // 传 null 统计全部比赛
$stats   = getCardStats($pdo, $matchId);
$result  = compareCards($stats);
print_r($stats);
echo $result['message'] . PHP_EOL;

输出示例

Array
(
    [0] => Array
        (
            [team_id] => 1
            [team_name] => 主队A
            [yellow_count] => 4
            [red_count] => 1
            [total_count] => 5
            [score] => 6
        )
    [1] => Array
        (
            [team_id] => 2
            [team_name] => 客队B
            [yellow_count] => 2
            [red_count] => 0
            [total_count] => 2
            [score] => 2
        )
)
主队A 牌更多(黄牌4张/红牌1张,加权6分),比 客队B 多 4 分

关键点说明

要点 说明
计数方式 用 SUM(card_type='yellow') 技巧,MySQL 中布尔值即 0/1,避免多次 COUNT 子查询
比较标准 直接比"总牌数"往往不合理(1红 vs 3黄),建议用加权分(黄1分/红2分),可按业务调整
排序 ORDER BY 先按加权分 DESC,再按 red_count DESC,确保红牌多者靠前
平局处理 分数、黄牌、红牌全部相等时判定为平局
性能 给 match_id、team_id 建索引;大表可加 card_type 联合索引

进阶:按赛事/赛季统计

// 只统计某个赛季或联赛
$sql = "
    SELECT t.team_name,
           SUM(c.card_type='yellow') AS yellow,
           SUM(c.card_type='red')    AS red
    FROM match_cards c
    JOIN matches m ON m.id = c.match_id
    JOIN teams   t ON t.id = c.team_id
    WHERE m.season = :season
    GROUP BY c.team_id
    ORDER BY (red*2 + yellow) DESC
    LIMIT 10
";

这样就可以灵活地输出「红黄牌最多/最少的球队排行榜」。

如果你有具体的数据表结构或需要 Laravel / ThinkPHP 版本的写法,可以把字段发我,我帮你改造成对应框架的查询构造器版本。

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