MySQL Where Clause with Union All 得到错误的结果

MySQL Where Clause with Union All getting wrong results

我会先说我仍在学习 MySQL,我绝对处于那个我知道足够危险的阶段。

我有一个数据库,其中包含体育联盟的记分数据。我们将 wins/losses 记为 1 分或零分。有一个晚上涉及双打(意味着玩家在一个晚上玩两次,用于 2 种不同的格式)。我的数据结构如下(只是一个示例,我有数百行,格式不同):

ID FID WK Type HomeTeam AwayTeam HF1 HF2 AF1 AF2
1 44 1 PL TM1 TM2 1 0 0 1
2 44 1 PL TM3 TM4 0 0 1 1
3 44 2 PL TM2 TM3 1 1 0 0
4 44 2 PL TM4 TM1 0 1 1 0
5 44 3 PL TM3 TM1 999 0 999 1
6 44 3 PL Tm2 TM4 1 0 0 1

其中 999 用作代码,让我们知道比赛尚未进行,或者得分表尚未交给我们进行记录保存。 (我使用 PHP 将这些调用到网站,供用户查看发生了什么,并使用 IF 语句将网站上的 999 转换为“TBD”)

我可以分别提取格式 1 和格式 2 的分数并得到一个很好的列表,但是当我尝试将它们放在一起并得到总分时,我得到的计数不正确。我知道错误出在我的 WHERE 子句上,但我一直在努力让它正常工作,我想我只需要对此多加注意。

我目前的SQL查询如下:

SELECT Team, 
       SUM(TotalF1) AS TotalF1, 
       SUM(TotalF2) AS TotalF2, 
       SUM(TotalF1+TotalF2) AS Total
FROM ( ( SELECT HomeTeam AS Team, 
                HF1 AS TotalF1, 
                HF2 AS TotalF2 
         FROM tbl_teamscores 
         WHERE FID = 44 
           AND Type = 'PL' 
           AND HF1 != 999 
           AND HF2 != 999 ) 
       UNION ALL 
       ( SELECT AwayTeam, 
                AF1, 
                AF2 
         FROM tbl_teamscores 
         WHERE FID = 44 
           AND Type = 'PL' 
           AND AF1 != 999 
           AND AF2 != 999 )
      ) CC 
GROUP BY Team 
ORDER BY Total desc, Team ASC;

虽然我得到的总数不正确,但我知道原因是因为那些 999 的指定,因为 WHERE 子句跳过了主场或客场得分匹配 999 的所有行。

我尝试将它分成 4 个单独的 Select 语句,然后将它们联合起来,但是当我这样做时我只是得到了一个错误。我也尝试过使用 Inner Join,但 MySQL 似乎也不喜欢那样。

编辑 添加 DBFiddle with Real World Table 数据和查询:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=1d4d090b08b8280e734218ba32db6d88 查看玩家 10 的数据时可以观察到问题的一个示例。总总数应该是 13,但我只得到 12。

任何建议都会很有帮助。

提前致谢!

您可以使用条件聚合:

SELECT Team, 
       SUM(CASE WHEN Total8 <> 999 THEN Total8 END) AS Total8, 
       SUM(CASE WHEN TotalLO <> 999 THEN TotalLO END) AS TotalLO, 
       SUM(CASE WHEN Total8 <> 999 THEN Total8 END) + SUM(CASE WHEN TotalLO <> 999 THEN TotalLO END) AS Total
FROM (
  SELECT HomeTeam AS Team, Home8PTS AS Total8, HomeLOPTS AS TotalLO FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL' 
  UNION ALL 
  SELECT AwayTeam, Away8PTS, AwayLOPTS FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL' 
) CC 
GROUP BY Team 
ORDER BY Team ASC;

或:

SELECT Team, 
       SUM(NULLIF(Total8, 999)) AS Total8, 
       SUM(NULLIF(TotalLO, 999)) AS TotalLO, 
       SUM(NULLIF(Total8, 999)) + SUM(NULLIF(TotalLO, 999)) AS Total
FROM (
  SELECT HomeTeam AS Team, Home8PTS AS Total8, HomeLOPTS AS TotalLO FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL' 
  UNION ALL 
  SELECT AwayTeam, Away8PTS, AwayLOPTS FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL' 
) CC 
GROUP BY Team 
ORDER BY Team ASC;

如果你在结果中得到 nulls 那么你也应该使用 COALESCE():

SELECT Team, 
       COALESCE(SUM(NULLIF(Total8, 999)), 0) AS Total8, 
       COALESCE(SUM(NULLIF(TotalLO, 999)), 0) AS TotalLO, 
       COALESCE(SUM(NULLIF(Total8, 999)), 0) + COALESCE(SUM(NULLIF(TotalLO, 999)), 0) AS Total
FROM (
  SELECT HomeTeam AS Team, Home8PTS AS Total8, HomeLOPTS AS TotalLO FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL' 
  UNION ALL 
  SELECT AwayTeam, Away8PTS, AwayLOPTS FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL' 
) CC 
GROUP BY Team 
ORDER BY Team ASC;

参见demo