Mysql 左连接中的多行导致重复数据

Mysql 左连接中的多行导致重复数据,mysql,sql,Mysql,Sql,我有一个相当复杂的MySQL查询,用于从下表检索球队及其联赛表现: 团队 分区/季/队 团队点调整 火柴 问题是: "SELECT t.name AS team_name, t.id as team_id, SUM(win) AS win, SUM(draw) AS draw, SUM(loss) AS loss, SUM(goals_for) AS goals_for, SUM(g

我有一个相当复杂的MySQL查询,用于从下表检索球队及其联赛表现:

团队

分区/季/队

团队点调整

火柴

问题是:

"SELECT 
        t.name AS team_name,
        t.id as team_id,
        SUM(win) AS win,
        SUM(draw) AS draw,
        SUM(loss) AS loss,
        SUM(goals_for) AS goals_for,
        SUM(goals_against) AS goals_against,
        SUM(goal_difference) as goal_difference,
        SUM(games_played) AS games_played,
        SUM(points) + IFNULL(tpa.point_adjustment, 0) as points
        FROM teams t 
        LEFT JOIN team_point_adjustments tpa
            ON t.id = tpa.team_id
            AND (tpa.season_id = 1 OR tpa.season_id IS NULL)
        INNER JOIN
            division_season_team dst
            ON t.id = dst.team_id
        LEFT JOIN (
            SELECT home_id
                team_name,
                IF(home_SCORE > away_score, 1,0) win,
                IF(home_score = away_score, 1,0) draw,
                IF(home_score < away_score, 1,0) loss,
                home_score goals_for,
                away_score goals_against,
                home_score - away_score goal_difference,
                1 games_played,
                CASE WHEN home_score > away_score THEN 5 WHEN home_score = away_score THEN 2 ELSE 0 END points
            FROM matches mat WHERE played = 1 AND season_id = 1 AND division_id = 1
            UNION ALL 
            SELECT away_id,
                IF(home_score < away_score, 1, 0),
                IF(home_score = away_score, 1,0),
                IF(home_score > away_score, 1,0),
                away_score,
                home_score,
                away_score - home_score goal_difference,
                1 games_played,
                CASE WHEN home_score < away_score THEN 5 WHEN home_score = away_score THEN 2 ELSE 0 END
            FROM matches
            WHERE played = 1 AND season_id = 1 AND division_id = 1
            ) AS total ON total.team_name=t.id WHERE dst.season_id = 1 AND dst.division_id = 1
        GROUP BY t.id
        ORDER BY points DESC, goal_difference DESC"
问题在于第一次左键加入团队的调整。如果两行匹配,即有两行对应于一个队,返回的数据是原来的两倍-玩过的游戏、赢过的游戏、得分等都是原来的两倍


已尝试为此子查询添加group by子句,但出现语法错误。如果此左联接中只有一个匹配行,则数据都是正确的。

如果重复行上的数据完全相同,则DISTINCT在这里会有所帮助

选择不同的 t、 以团队名称命名, t、 id作为团队id, SUMwin作为win, 素描即画, 把损失当作损失, 将目标作为目标, ... etc

在加入前,将表上的比赛和表上的赛区队进行汇总,这两个赛区都必须离开,以防万一:

SELECT 
        t.name AS team_name,
        t.id as team_id,
        total.win,
        total.draw,
        total.loss,
        total.goals_for,
        total.goals_against,
        total.goal_difference,
        total.games_played,
        total.points + IFNULL(tpa.point_adjustment, 0) as points
FROM teams t 
LEFT JOIN (
  SELECT team_id, season_id, SUM(point_adjustment) AS point_adjustment
  FROM team_point_adjustments
  GROUP BY team_id, season_id
) tpa
ON t.id = tpa.team_id AND (tpa.season_id = '" . $season_id . "' OR tpa.season_id IS NULL)
LEFT JOIN division_season_team dst ON t.id = dst.team_id
LEFT JOIN (
          SELECT
            g.team_id,
            g.team_name,
            SUM(g.win) AS win,
            SUM(g.draw) AS draw,
            SUM(g.loss) AS loss,
            SUM(g.goals_for) AS goals_for,
            SUM(g.goals_against) AS goals_against,
            SUM(g.goal_difference) as goal_difference,
            SUM(g.g.games_played) AS games_played,
            SUM(points) AS points
          FROM (
            SELECT home_id
                team_name,
                IF(home_SCORE > away_score, 1,0) win,
                IF(home_score = away_score, 1,0) draw,
                IF(home_score < away_score, 1,0) loss,
                home_score goals_for,
                away_score goals_against,
                home_score - away_score goal_difference,
                1 games_played,
                CASE WHEN home_score > away_score THEN '" . $win_value . "' WHEN home_score = away_score THEN '" . $draw_value . "' ELSE '" . $loss_value . "' END points
            FROM matches mat WHERE played = 1 AND season_id = '" . $season_id . "' AND division_id = '" . $division_id . "'
            UNION ALL 
            SELECT away_id,
                IF(home_score < away_score, 1, 0),
                IF(home_score = away_score, 1,0),
                IF(home_score > away_score, 1,0),
                away_score,
                home_score,
                away_score - home_score goal_difference,
                1 games_played,
                CASE WHEN home_score < away_score THEN '" . $win_value . "' WHEN home_score = away_score THEN '" . $draw_value . "' ELSE '" . $loss_value . "' END
            FROM matches
            WHERE played = 1 AND season_id = '" . $season_id . "' AND division_id = '" . $division_id . "'
          ) g
          GROUP BY g.team_id, f.team_name       
) AS total ON total.team_id=t.id 
WHERE dst.season_id = '" . $season_id . "' AND dst.division_id = '" . $division_id . "'
ORDER BY points DESC, goal_difference DESC

我希望我没有输入错误…

如果您查看表格结构,每次添加日期、添加或扣除的点数,团队点数调整中的数据都会有所不同,这也是扣除的原因之一。您可能永远不需要在包含聚合函数SSUMTPA的查询中使用不同的修饰符。点数调整?还有,我认为将PHP变量合并到这个问题中会增加不必要的混乱。在任何情况下,这些都应该是适当准备和绑定查询的占位符。但是point\u adjustment不在division\u season\u team表中,因此我得到一个列not found error
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| id               | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| point_adjustment | int(11)          | NO   |     | 0       |                |
| reason           | varchar(191)     | NO   |     | NULL    |                |
| reason_date      | date             | NO   |     | NULL    |                |
| team_id          | int(10) unsigned | YES  | MUL | NULL    |                |
| season_id        | int(10) unsigned | YES  | MUL | NULL    |                |
| created_at       | timestamp        | YES  |     | NULL    |                |
| updated_at       | timestamp        | YES  |     | NULL    |                |
+------------------+------------------+------+-----+---------+----------------+
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| home_score  | int(11)          | NO   |     | 0       |                |
| away_score  | int(11)          | NO   |     | 0       |                |
| division_id | int(10) unsigned | YES  | MUL | NULL    |                |
| season_id   | int(10) unsigned | YES  | MUL | NULL    |                |
| home_id     | int(10) unsigned | YES  | MUL | NULL    |                |
| away_id     | int(10) unsigned | YES  | MUL | NULL    |                |
| match_date  | datetime         | NO   |     | NULL    |                |
| court       | int(10) unsigned | NO   |     | NULL    |                |
| round       | int(10) unsigned | NO   |     | NULL    |                |
| played      | tinyint(1)       | NO   |     | 0       |                |
| walkover    | tinyint(1)       | NO   |     | 0       |                |
| home_adjust | int(11)          | NO   |     | 0       |                |
| away_adjust | int(11)          | NO   |     | 0       |                |
| created_at  | timestamp        | YES  |     | NULL    |                |
| updated_at  | timestamp        | YES  |     | NULL    |                |
| deleted_at  | timestamp        | YES  |     | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+
"SELECT 
        t.name AS team_name,
        t.id as team_id,
        SUM(win) AS win,
        SUM(draw) AS draw,
        SUM(loss) AS loss,
        SUM(goals_for) AS goals_for,
        SUM(goals_against) AS goals_against,
        SUM(goal_difference) as goal_difference,
        SUM(games_played) AS games_played,
        SUM(points) + IFNULL(tpa.point_adjustment, 0) as points
        FROM teams t 
        LEFT JOIN team_point_adjustments tpa
            ON t.id = tpa.team_id
            AND (tpa.season_id = 1 OR tpa.season_id IS NULL)
        INNER JOIN
            division_season_team dst
            ON t.id = dst.team_id
        LEFT JOIN (
            SELECT home_id
                team_name,
                IF(home_SCORE > away_score, 1,0) win,
                IF(home_score = away_score, 1,0) draw,
                IF(home_score < away_score, 1,0) loss,
                home_score goals_for,
                away_score goals_against,
                home_score - away_score goal_difference,
                1 games_played,
                CASE WHEN home_score > away_score THEN 5 WHEN home_score = away_score THEN 2 ELSE 0 END points
            FROM matches mat WHERE played = 1 AND season_id = 1 AND division_id = 1
            UNION ALL 
            SELECT away_id,
                IF(home_score < away_score, 1, 0),
                IF(home_score = away_score, 1,0),
                IF(home_score > away_score, 1,0),
                away_score,
                home_score,
                away_score - home_score goal_difference,
                1 games_played,
                CASE WHEN home_score < away_score THEN 5 WHEN home_score = away_score THEN 2 ELSE 0 END
            FROM matches
            WHERE played = 1 AND season_id = 1 AND division_id = 1
            ) AS total ON total.team_name=t.id WHERE dst.season_id = 1 AND dst.division_id = 1
        GROUP BY t.id
        ORDER BY points DESC, goal_difference DESC"
{
    "team_name": "Jets",
    "team_id": 20,
    "win": "8",
    "draw": "0",
    "loss": "4",
    "goals_for": "354",
    "goals_against": "265",
    "goal_difference": "89",
    "games_played": "12",
    "points": 40
}
SELECT 
        t.name AS team_name,
        t.id as team_id,
        total.win,
        total.draw,
        total.loss,
        total.goals_for,
        total.goals_against,
        total.goal_difference,
        total.games_played,
        total.points + IFNULL(tpa.point_adjustment, 0) as points
FROM teams t 
LEFT JOIN (
  SELECT team_id, season_id, SUM(point_adjustment) AS point_adjustment
  FROM team_point_adjustments
  GROUP BY team_id, season_id
) tpa
ON t.id = tpa.team_id AND (tpa.season_id = '" . $season_id . "' OR tpa.season_id IS NULL)
LEFT JOIN division_season_team dst ON t.id = dst.team_id
LEFT JOIN (
          SELECT
            g.team_id,
            g.team_name,
            SUM(g.win) AS win,
            SUM(g.draw) AS draw,
            SUM(g.loss) AS loss,
            SUM(g.goals_for) AS goals_for,
            SUM(g.goals_against) AS goals_against,
            SUM(g.goal_difference) as goal_difference,
            SUM(g.g.games_played) AS games_played,
            SUM(points) AS points
          FROM (
            SELECT home_id
                team_name,
                IF(home_SCORE > away_score, 1,0) win,
                IF(home_score = away_score, 1,0) draw,
                IF(home_score < away_score, 1,0) loss,
                home_score goals_for,
                away_score goals_against,
                home_score - away_score goal_difference,
                1 games_played,
                CASE WHEN home_score > away_score THEN '" . $win_value . "' WHEN home_score = away_score THEN '" . $draw_value . "' ELSE '" . $loss_value . "' END points
            FROM matches mat WHERE played = 1 AND season_id = '" . $season_id . "' AND division_id = '" . $division_id . "'
            UNION ALL 
            SELECT away_id,
                IF(home_score < away_score, 1, 0),
                IF(home_score = away_score, 1,0),
                IF(home_score > away_score, 1,0),
                away_score,
                home_score,
                away_score - home_score goal_difference,
                1 games_played,
                CASE WHEN home_score < away_score THEN '" . $win_value . "' WHEN home_score = away_score THEN '" . $draw_value . "' ELSE '" . $loss_value . "' END
            FROM matches
            WHERE played = 1 AND season_id = '" . $season_id . "' AND division_id = '" . $division_id . "'
          ) g
          GROUP BY g.team_id, f.team_name       
) AS total ON total.team_id=t.id 
WHERE dst.season_id = '" . $season_id . "' AND dst.division_id = '" . $division_id . "'
ORDER BY points DESC, goal_difference DESC