admin 管理员组文章数量: 1086019
I am trying to combine 3 queries, but it doesn't work well. Separately they work very well. It is about the following. I want to search for all games the user has participated in, user - '$POSTCharID'
Per game points can be earned with home and away team. And here it goes wrong. The points do not match the given data.
It is checked which player is in which team, has participated and is ready. Didn't participate and not ready - 1ptn Did participate and not ready - 5ptn Didn't participate and ready - 10ptn Did participate and ready - 15ptn
Table - GameParti
GameParti_Lnk_ID | CreationDate | LeagueGames_ID | CharacterID | SupportTeam | CreatedByAccountID | CreatedByCharacterID |
---|---|---|---|---|---|---|
19 | 24/03/2025 9:54 | 9 | 20 | 3 | 11 | 20 |
12 | 17/03/2025 14:39 | 9 | 61 | 3 | 11 | 61 |
13 | 18/03/2025 21:42 | 9 | 56 | 3 | 11 | 56 |
14 | 19/03/2025 12:15 | 9 | 62 | 3 | 11 | 62 |
15 | 19/03/2025 12:40 | 9 | 64 | 3 | 23 | 64 |
16 | 19/03/2025 12:42 | 9 | 63 | 3 | 11 | 63 |
17 | 21/03/2025 12:56 | 9 | 59 | 3 | 11 | 59 |
20 | 24/03/2025 16:36 | 9 | 25 | 3 | 23 | 25 |
21 | 24/03/2025 22:12 | 9 | 31 | 3 | 11 | 31 |
22 | 25/03/2025 9:54 | 9 | 12 | 3 | 11 | 12 |
23 | 26/03/2025 17:49 | 8 | 12 | 3 | 11 | 12 |
I am trying to combine 3 queries, but it doesn't work well. Separately they work very well. It is about the following. I want to search for all games the user has participated in, user - '$POSTCharID'
Per game points can be earned with home and away team. And here it goes wrong. The points do not match the given data.
It is checked which player is in which team, has participated and is ready. Didn't participate and not ready - 1ptn Did participate and not ready - 5ptn Didn't participate and ready - 10ptn Did participate and ready - 15ptn
Table - GameParti
GameParti_Lnk_ID | CreationDate | LeagueGames_ID | CharacterID | SupportTeam | CreatedByAccountID | CreatedByCharacterID |
---|---|---|---|---|---|---|
19 | 24/03/2025 9:54 | 9 | 20 | 3 | 11 | 20 |
12 | 17/03/2025 14:39 | 9 | 61 | 3 | 11 | 61 |
13 | 18/03/2025 21:42 | 9 | 56 | 3 | 11 | 56 |
14 | 19/03/2025 12:15 | 9 | 62 | 3 | 11 | 62 |
15 | 19/03/2025 12:40 | 9 | 64 | 3 | 23 | 64 |
16 | 19/03/2025 12:42 | 9 | 63 | 3 | 11 | 63 |
17 | 21/03/2025 12:56 | 9 | 59 | 3 | 11 | 59 |
20 | 24/03/2025 16:36 | 9 | 25 | 3 | 23 | 25 |
21 | 24/03/2025 22:12 | 9 | 31 | 3 | 11 | 31 |
22 | 25/03/2025 9:54 | 9 | 12 | 3 | 11 | 12 |
23 | 26/03/2025 17:49 | 8 | 12 | 3 | 11 | 12 |
Table - LeagueGames
LeagueGames_ID | CreationDate | Score_HomeTeam | Home_ClubID | Home_ClubName | Home_TeamID | Home_TeamName | Score_AwayTeam | Away_ClubID | Away_ClubName | Away_TeamID | Away_TeamName | LeagueGame_Status |
---|---|---|---|---|---|---|---|---|---|---|---|---|
8 | 31/01/2025 16:51 | 2 | 2 | Club Talo | 3 | Team Gholo | 1 | 14 | Club Mipu | 38 | Team Vruup | 2 |
9 | 13/03/2025 14:14 | 0 | 3 | Club Froly | 11 | Team Hiruo | 2 | 2 | Club Talo | 3 | Team Gholo | 4 |
Table - Teams
TeamID | Club_ID | Club_Name | Team_Name |
---|---|---|---|
3 | 2 | Club Talo | Team Gholo |
11 | 3 | Club Froly | Team Hiruo |
38 | 14 | Club Mipu | Team Vruup |
Table - Clubs
ClubID | Clubname |
---|---|
2 | Club Talo |
3 | Club Froly |
14 | Club Mipu |
Table - TeamPlayerLnk
TeamPlayers_Lnk_ID | CharacterID | Teamplayer_ClubID | Teamplayer_TeamID | ActLinked |
---|---|---|---|---|
2 | 59 | 2 | 3 | 1 |
3 | 60 | 2 | 3 | 1 |
4 | 61 | 2 | 3 | 1 |
5 | 63 | 2 | 3 | 1 |
6 | 64 | 3 | 11 | 1 |
7 | 65 | 3 | 11 | 1 |
8 | 66 | 2 | 3 | 1 |
9 | 67 | 2 | 3 | 1 |
10 | 68 | 2 | 3 | 1 |
Table - Characters
AccountID | ID | Firstname | LastName |
---|---|---|---|
6 | 11 | FirstPlayer 1 | LastPlayer1 |
11 | 12 | FirstPlayer 2 | LastPlayer2 |
5 | 13 | FirstPlayer 3 | LastPlayer3 |
11 | 20 | FirstPlayer 4 | LastPlayer4 |
11 | 62 | FirstPlayer 5 | LastPlayer5 |
0 | 53 | FirstPlayer 6 | LastPlayer6 |
23 | 25 | FirstPlayer 7 | LastPlayer7 |
22 | 30 | FirstPlayer 8 | LastPlayer8 |
11 | 31 | FirstPlayer 9 | LastPlayer9 |
0 | 60 | FirstPlayer 10 | LastPlayer10 |
11 | 61 | FirstPlayer 11 | LastPlayer11 |
0 | 54 | FirstPlayer 12 | LastPlayer12 |
0 | 52 | FirstPlayer 13 | LastPlayer13 |
0 | 51 | FirstPlayer 14 | LastPlayer14 |
0 | 55 | FirstPlayer 15 | LastPlayer15 |
11 | 56 | FirstPlayer 16 | LastPlayer16 |
11 | 59 | FirstPlayer 17 | LastPlayer17 |
11 | 63 | FirstPlayer 18 | LastPlayer18 |
23 | 64 | FirstPlayer 19 | LastPlayer19 |
0 | 65 | FirstPlayer 20 | LastPlayer20 |
0 | 66 | FirstPlayer 21 | LastPlayer21 |
0 | 67 | FirstPlayer 22 | LastPlayer22 |
0 | 69 | FirstPlayer 23 | LastPlayer23 |
Table - PlayerReady
PlayerReady_ID | CreatedByCharacterID | ActLinked |
---|---|---|
61 | 20 | 1 |
60 | 20 | 1 |
59 | 20 | 1 |
59 | 31 | 1 |
61 | 25 | 1 |
65 | 20 | 1 |
64 | 25 | 1 |
65 | 25 | 1 |
60 | 25 | 1 |
64 | 20 | 1 |
67 | 25 | 1 |
59 | 12 | 1 |
$POSTCharID - 20 - Result Now - Points don't match
CreationDate | hScore | hClubName | hTeamName | aScore | aClubName | aTeamName | sGameStatus | HomeTotalPts | AwayTotalPts |
---|---|---|---|---|---|---|---|---|---|
13/03/2025 14:14 | 0 | Club Froly | Team Hiruo | 2 | Club Talo | Team Gholo | 4 | 350 | 192 |
$POSTCharID - 20 - Expected results
CreationDate | hScore | hClubName | hTeamName | aScore | aClubName | aTeamName | sGameStatus | HomeTotalPts | AwayTotalPts |
---|---|---|---|---|---|---|---|---|---|
13/03/2025 14:14 | 0 | Club Froly | Team Hiruo | 2 | Club Talo | Team Gholo | 4 | 25 | 47 |
$POSTCharID - 12 - Result Now - Points don't match AND echo only 1 game instead of 2 games
CreationDate | hScore | hClubName | hTeamName | aScore | aClubName | aTeamName | sGameStatus | HomeTotalPts | AwayTotalPts |
---|---|---|---|---|---|---|---|---|---|
13/03/2025 14:14 | 0 | Club Froly | Team Hiruo | 2 | Club Talo | Team Gholo | 4 | 58 | 65 |
$POSTCharID - 12 - Expected results
CreationDate | hScore | hClubName | hTeamName | aScore | aClubName | aTeamName | sGameStatus | HomeTotalPts | AwayTotalPts |
---|---|---|---|---|---|---|---|---|---|
31/01/2025 16:51 | 2 | Club Talo | Team Gholo | 1 | Club Mipu | Team Vruup | 2 | 15 | 0 |
13/03/2025 14:14 | 0 | Club Froly | Team Hiruo | 2 | Club Talo | Team Gholo | 4 | 6 | 28 |
SELECT
s.CreationDate AS sCreationDate,
s.Score_HomeTeam AS hScore,
hc.Clubname AS hClubName,
ht.Team_Name AS hTeamName,
s.Score_AwayTeam AS aScore,
ac.Clubname AS aClubName,
at.Team_Name AS aTeamName,
s.LeagueGame_Status AS sGameStatus,
sum(CASE WHEN z1.LeagueGames_ID IS NULL AND p1.PlayerReady_ID IS NULL THEN '1'
WHEN z1.LeagueGames_ID IS NOT NULL AND p1.PlayerReady_ID IS NULL THEN '5'
WHEN z1.LeagueGames_ID IS NULL AND p1.PlayerReady_ID IS NOT NULL THEN '10'
WHEN z1.LeagueGames_ID IS NOT NULL AND p1.PlayerReady_ID IS NOT NULL THEN '15' ELSE 0 END) AS HomeTotalPts,
sum(CASE WHEN z2.LeagueGames_ID IS NULL AND p2.PlayerReady_ID IS NULL THEN '1'
WHEN z2.LeagueGames_ID IS NOT NULL AND p2.PlayerReady_ID IS NULL THEN '5'
WHEN z2.LeagueGames_ID IS NULL AND p2.PlayerReady_ID IS NOT NULL THEN '10'
WHEN z2.LeagueGames_ID IS NOT NULL AND p2.PlayerReady_ID IS NOT NULL THEN '15' ELSE 0 END) AS AwayTotalPts
FROM GameParti e
LEFT JOIN LeagueGames s ON s.LeagueGames_ID = e.LeagueGames_ID
LEFT JOIN Teams ht ON ht.TeamID = s.Home_TeamID
LEFT JOIN Clubs hc ON hc.ClubID = ht.Club_ID
LEFT JOIN Teams at ON at.TeamID = s.Away_TeamID
LEFT JOIN Clubs ac ON ac.ClubID = at.Club_ID
LEFT JOIN TeamPlayerLnk g1 ON g1.Teamplayer_TeamID = ht.TeamID AND g1.ActLinked = '1'
LEFT JOIN Characters c1 ON c1.ID = g1.CharacterID
LEFT JOIN GameParti z1 ON z1.CharacterID = g1.CharacterID AND z1.LeagueGames_ID = s.LeagueGames_ID
LEFT JOIN PlayerReady p1 ON p1.PlayerReady_ID = g1.CharacterID AND p1.ActLinked = '1' AND p1.CreatedByCharacterID='$POSTCharID'
LEFT JOIN TeamPlayerLnk g2 ON g2.Teamplayer_TeamID = at.TeamID AND g2.ActLinked = '1'
LEFT JOIN Characters c2 ON c2.ID = g2.CharacterID
LEFT JOIN GameParti z2 ON z2.CharacterID = g2.CharacterID AND z2.LeagueGames_ID = s.LeagueGames_ID
LEFT JOIN PlayerReady p2 ON p2.PlayerReady_ID = g2.CharacterID AND p2.ActLinked = '1' AND p2.CreatedByCharacterID='$POSTCharID'
WHERE e.CharacterID = '$POSTCharID' ORDER BY CreationDate;
This is the data I get when I run the query separately.
POSTCharID 12 and game 9 – Hometeam Player Points - Total 6
Teamplayer ID | participated | Ready | Points |
---|---|---|---|
64 | 1 | 0 | 5 |
65 | 0 | 0 | 1 |
POSTCharID 12 and game 9 – Awayteam Player Points - Total 28
Teamplayer ID | participated | Ready | Points |
---|---|---|---|
59 | 1 | 1 | 15 |
61 | 1 | 0 | 5 |
63 | 1 | 0 | 5 |
60 | 0 | 0 | 1 |
66 | 0 | 0 | 1 |
67 | 0 | 0 | 1 |
Thanks for your help!
Share Improve this question edited Mar 28 at 18:43 Barmar 784k57 gold badges548 silver badges660 bronze badges asked Mar 27 at 9:29 Dimko 696Dimko 696 351 silver badge6 bronze badges 11 | Show 6 more comments1 Answer
Reset to default 4- Your problem lies in that joining your main table to subtables that have respectively m and n rows for 1 row in your main table, will multiply by m the sum of the n-rows table, and by n the sum of the m-rows table.
- There is no interaction between your Home and Away join groups until they are joined to
LeagueGames
, so you could compute them separately in two Common Table Expressions, before joining them toLeagueGames
in your final query - Additionally, they are fully symetrical: no need of 2 CTEs, you can mutualize them in 1 CTE
WITH
-- Protect against duplicates (20 that participated twice to the same game under IDs 11 and 19);
-- if we do not, our results will be multiplied by 2.
parti AS (SELECT DISTINCT LeagueGames_ID, CharacterID FROM GameParti),
points AS
(
SELECT
c.Clubname,
t.TeamID,
t.Team_Name,
e.LeagueGames_ID,
e.CharacterID CreatedByCharacterID,
sum(CASE WHEN z.LeagueGames_ID IS NULL AND p.PlayerReady_ID IS NULL THEN '1'
WHEN z.LeagueGames_ID IS NOT NULL AND p.PlayerReady_ID IS NULL THEN '5'
WHEN z.LeagueGames_ID IS NULL AND p.PlayerReady_ID IS NOT NULL THEN '10'
WHEN z.LeagueGames_ID IS NOT NULL AND p.PlayerReady_ID IS NOT NULL THEN '15' ELSE 0 END) AS TotalPts
FROM parti e
JOIN LeagueGames s ON s.LeagueGames_ID = e.LeagueGames_ID
JOIN Teams t ON t.TeamID IN (s.Home_TeamID, s.Away_TeamID)
JOIN Clubs c ON c.ClubID = t.Club_ID
JOIN TeamPlayerLnk g ON g.Teamplayer_TeamID = t.TeamID AND g.ActLinked = '1'
JOIN Characters ch ON ch.ID = g.CharacterID
LEFT JOIN GameParti z ON z.CharacterID = g.CharacterID AND z.LeagueGames_ID = s.LeagueGames_ID
LEFT JOIN PlayerReady p ON p.PlayerReady_ID = g.CharacterID AND p.ActLinked = '1' AND p.CreatedByCharacterID = e.CharacterID
GROUP BY 1, 2, 3, 4, 5
)
SELECT
e.CharacterID,
s.CreationDate AS sCreationDate,
s.Score_HomeTeam AS hScore,
ht.Clubname AS hClubName,
ht.Team_Name AS hTeamName,
s.Score_AwayTeam AS aScore,
at.Clubname AS aClubName,
at.Team_Name AS aTeamName,
s.LeagueGame_Status AS sGameStatus,
ht.TotalPts AS HomeTotalPts,
at.TotalPts AS AwayTotalPts
FROM parti e
LEFT JOIN LeagueGames s ON s.LeagueGames_ID = e.LeagueGames_ID
LEFT JOIN points ht ON ht.TeamID = s.Home_TeamID AND ht.LeagueGames_ID = e.LeagueGames_ID AND ht.CreatedByCharacterID = e.CharacterID
LEFT JOIN points at ON at.TeamID = s.Away_TeamID AND at.LeagueGames_ID = e.LeagueGames_ID AND at.CreatedByCharacterID = e.CharacterID
WHERE e.CharacterID = '$POSTCharID'
ORDER BY 1, 2;
characterid | screationdate | hscore | hclubname | hteamname | ascore | aclubname | ateamname | sgamestatus | hometotalpts | awaytotalpts |
---|---|---|---|---|---|---|---|---|---|---|
12 | 13/03/2025 14:14 | 0 | Club Froly | Team Hiruo | 2 | Club Talo | Team Gholo | 4 | 6 | 28 |
12 | 31/01/2025 16:51 | 2 | Club Talo | Team Gholo | 1 | 2 | 15 | |||
20 | 13/03/2025 14:14 | 0 | Club Froly | Team Hiruo | 2 | Club Talo | Team Gholo | 4 | 25 | 47 |
(see it in a fiddle)
0-player twist
Note that those results still need one additional twist on NULL
-returning LEFT JOIN
s:
They are necessary to give 1 point to a team registered to a game, but whose players where either not participating or not ready.
But the LEFT JOIN
should apply to participation or readiness of the characters, not their existence; in the particular case of Team Vruup that has literally 0 character (and thus cannot get one ready), left joining all tables will result in a "virtual character" with all values set to NULL
still adding 1 point.
Thus we would get 1 instead of the intended 0 for the game against Team Gholo;
and similarly (although I didn't diagnose in details) Team Gholo received an additional point in its Away games, thus totaling 29 and 48 instead of 28 and 47.
So the LEFT JOIN
are reserved for the last step, the ones ensuring the characters are 1. participating and 2. ready.
The other ones are (INNER
) JOIN
s, ensuring that a team participating to a game exists, that the club it belongs to exists, and it has at least one player to engage.
But then, a JOIN
with 0 character will result in 0 row instead of 1 with NULL
characters: thus it creates a new problem: we don't even get the team's name.
This is why some twist will be necessary to either not count the additional 1, or reconstitute team and club name.
Additional need: subtract already collected points
As seen in the comments, if some points already have been attributed, they should be deduced from the total "to distribute".
As this table gets its primary key from TeamID, LeagueGameID
, it should naturally be injected after points
(not during points: that would add the points once per character).
But we can rely on the same technique than for points
(computing independently from the fact this is the Home or the Guest team),
by adding a dedicated CTE.
We transform the query this way:
WITH points AS (…), -- No change here
points2 AS -- Add points2, which is points enriched by one new field.
(
SELECT p.*, COALESCE(EarnedPoints, 0) AlreadyCollectedPts
FROM points p LEFT JOIN CollectedPoints cp ON cp.LeagueGames_ID = p.LeagueGames_ID AND cp.TeamID = p.TeamID
)
SELECT
…, -- No change until AwayTotalPts
-- Add new fields:
ht.TotalPts - ht.AlreadyCollectedPts AS HomePtsToCollect,
at.TotalPts - at.AlreadyCollectedPts AS AwayPtsToCollect
FROM …
LEFT JOIN points2 ht ON … -- Instead of points
LEFT JOIN points2 at ON … -- Same here
…; -- No change
本文标签: mariadbCombining 3 SQL queriesStack Overflow
版权声明:本文标题:mariadb - Combining 3 SQL queries - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744100267a2533466.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
PlayerReady
table does not include anyActLinked
column, however your have two testsp1.ActLinked = '1'
andp2.ActLinked = '1'
. They do not look important in the process (I suppose they all are set to 1), but it would be necessary to add it to have a fully reproducible example. – Guillaume Outters Commented Mar 27 at 10:09