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;
如果你在结果中得到 null
s 那么你也应该使用 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。
我会先说我仍在学习 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;
如果你在结果中得到 null
s 那么你也应该使用 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。