将多个查询组合成一个查询时,如何将列汇总在一起

时间:2014-05-04 02:59:15

标签: mysql sql union-all

我正在尝试从匹配表中计算联赛积分。

+----------------------------------+
|              Matches             |
+----------------------------------+
| id                               |
| league_id (FK League)            |   
| season_id (FK Season)            |
| home_team_id (FK Team)           |
| away_team_id (FK Team)           | 
| home_score                       |
| away_score                       |
| confirmed                        |
+----------------------------------+

我可以使用此查询正确计算主场联赛积分榜:

SELECT team.name, home_team_id AS team_id,
    COUNT(*) AS played,
    SUM((CASE WHEN home_score > away_score THEN 1 ELSE 0 END)) AS won,
    SUM((CASE WHEN away_score > home_score THEN 1 ELSE 0 END)) AS lost,
    SUM((CASE WHEN home_score = away_score THEN 1 ELSE 0 END)) AS drawn,
    SUM(home_score) AS goalsFor,
    SUM(away_score) AS goalsAgainst,
    SUM(home_score - away_score) AS goalDifference,
    SUM((CASE WHEN home_score > away_score THEN 3 WHEN home_score = away_score THEN 1 ELSE 0 END)) AS points
FROM matches
INNER JOIN team ON matches.home_team_id = team.id
WHERE league_id = 94
    AND season_id = 82
    AND confirmed IS NOT NULL
GROUP BY home_team_id
ORDER BY POINTS DESC;

enter image description here

和Away League Standigns使用此查询:

SELECT team.name, away_team_id AS team_id,
    COUNT(*) AS played,
    SUM((CASE WHEN away_score > home_score THEN 1 ELSE 0 END)) AS won,
    SUM((CASE WHEN home_score > away_score THEN 1 ELSE 0 END)) AS lost,
    SUM((CASE WHEN home_score = away_score THEN 1 ELSE 0 END)) as drawn,
    SUM(away_score) AS goalsFor,
    SUM(home_score) AS goalsAgainst,
    SUM(away_score - home_score) AS goalDifference,
    SUM((CASE WHEN away_score > home_score THEN 3 WHEN away_score = home_score THEN 1 ELSE 0 END)) AS points
FROM matches
INNER JOIN team ON matches.away_team_id = team.id
WHERE league_id = 94
    AND season_id = 82
    AND confirmed IS NOT NULL
GROUP BY away_team_id
ORDER BY points DESC;

enter image description here

但是使用UNION ALL组合这两个查询我得不到正确的结果

SELECT * FROM 
(
    SELECT team.name, home_team_id AS team_id,
        COUNT(*) AS played,
        SUM((CASE WHEN home_score > away_score THEN 1 ELSE 0 END)) AS won,
        SUM((CASE WHEN away_score > home_score THEN 1 ELSE 0 END)) AS lost,
        SUM((CASE WHEN home_score = away_score THEN 1 ELSE 0 END)) AS drawn,
        SUM(home_score) AS goalsFor,
        SUM(away_score) AS goalsAgainst,
        SUM(home_score - away_score) AS goalDifference,
        SUM((CASE WHEN home_score > away_score THEN 3 WHEN home_score = away_score THEN 1 ELSE 0 END)) AS points
    FROM matches
    INNER JOIN team ON matches.home_team_id = team.id
    WHERE league_id = 94
        AND season_id = 82
        AND confirmed IS NOT NULL
    GROUP BY home_team_id
UNION
    SELECT team.name, away_team_id AS team_id,
        COUNT(*) AS played,
        SUM((CASE WHEN away_score > home_score THEN 1 ELSE 0 END)) AS won,
        SUM((CASE WHEN home_score > away_score THEN 1 ELSE 0 END)) AS lost,
        SUM((CASE WHEN home_score = away_score THEN 1 ELSE 0 END)) as drawn,
        SUM(away_score) AS goalsFor,
        SUM(home_score) AS goalsAgainst,
        SUM(away_score - home_score) AS goalDifference,
        SUM((CASE WHEN away_score > home_score THEN 3 WHEN away_score = home_score THEN 1 ELSE 0 END)) AS points
    FROM matches
    INNER JOIN team ON matches.away_team_id = team.id
    WHERE league_id = 94
        AND season_id = 82
        AND confirmed IS NOT NULL
    GROUP BY away_team_id
) x 
GROUP BY team_id
ORDER BY points DESC;

enter image description here

这应该是预期的结果:

enter image description here

对我做错了什么的任何想法?谢谢!

更新1:

尝试Dans查询不起作用:

选择team.name,HomePoints + AwayPoints积分 来自团队加入(     选择team.id,         总和(当home.home_score> home.away_score然后3             当home.home_score = home.away_score然后1其他0结束)HomePoints,         总和(例如当离开.away_score> away.home_score然后3其他0结束)AwayPoints     来自团队     在team.id = home.home_team_id上加入匹配主页     在team.id = away.away_team_id上加入比赛     home home.league_id = 94         AND home.season_id = 82         AND home.confirmed IS NOT NULL     按ID分组 )team.id = temp.id上的temp 按点desc排序;

我得到了这个结果:

enter image description here

4 个答案:

答案 0 :(得分:1)

您可能想要使用JOIN而不是UNION。 在两个都有team_id的子查询上使用UNION后,您在team_id上使用GROUP BY。 这不会起作用......如果你只是使用联接,你甚至可以省去小组。

答案 1 :(得分:0)

我会用这种方法。我只想做点。对于你想要的其他东西,逻辑是一样的。

select TeamName, HomePoints + AwayPoints points
from team join (
select team_id
, sum(case when home.home_score > home.away_score then 3
when home.home_score = home.away_score then 1 else 0 end) HomePoints
, sum(case when away.away_score > away.home_score then 3
when away.home_score = away.away_score then 1 else 0 end) AwayPoints
from team join matches home on team.team_id = home.home_team_id
join matches away on team.team_id = away.away_team_id
where blah blah blah
group by team_id
) temp on team.team_id = temp.team_id
order by points desc

答案 2 :(得分:0)

我想我知道发生了什么,但没有MySQL安装来测试它。

当您按查询进行分组时,不是分组的一部分的每一列必须是一个聚合函数(SUM,MAX等)。如果你不这样做,大多数数据库引擎会给你一个错误; MySQL试图提供帮助吗?通过选择随机行代替。

tl; dr你的外部选择需要一堆SUM而不是只选择*。

答案 3 :(得分:0)

试试这个:

SELECT team.name, 
       team_id AS team_id,
       COUNT(*) AS played,
       SUM((CASE WHEN team_score > other_team_score THEN 1 ELSE 0 END)) AS won,
       SUM((CASE WHEN team_score < other_team_score THEN 1 ELSE 0 END)) AS lost,
       SUM((CASE WHEN team_score = other_team_score THEN 1 ELSE 0 END)) AS drawn,
       SUM(team_score) AS goalsFor,
       SUM(other_team_score) AS goalsAgainst,
       SUM(team_score - other_team_score) AS goalDifference,
       SUM((CASE WHEN team_score > other_team_score THEN 3 
                 WHEN team_score = other_team_score THEN 1 
                 ELSE 0 END)) AS points
FROM
    (
        -- LIST TEAM STATS WHEN PLAYED AS HOME_TEAM
        SELECT 
             id                               
             league_id
             season_id
             home_team_id as team_id,
             home_score   as team_score,
             away_score   as other_team_score, 
             confirmed 
        FROM    matches
        UNION ALL
        -- LIST TEAM STATS WHEN PLAYED AS AWAY_TEAM
        SELECT 
             id                               
             league_id
             season_id
             away_team_id as team_id,
             away_score   as team_score,
             home_score   as other_team_score, 
             confirmed 
        FROM matches
    ) matches
INNER JOIN team ON matches.team_id = team.id
WHERE league_id = 94
    AND season_id = 82
    AND confirmed IS NOT NULL
GROUP BY team.name, team_id
ORDER BY POINTS DESC;
相关问题