I have the following two tables:
sport_a_statistics:
id team_id game_id points
1 1 1 7
2 2 1 8
3 3 2 6
4 1 2 9
sport_b_statistics:
id team_id game_id points
1 1 3 2
2 2 3 1
3 3 4 3
4 1 4 10
I want to calculate the win/loss ratio for each team. This includes making sure to capture the wins and losses from both sport tables since my tournament involves 2 sports. So the output I'm looking for is the following:
team_id wins loss ratio
1 3 1 3.0
2 1 1 1.0
3 0 2 0.0
I can't wrap my head around how I would do this in one query.
Assuming you have no ties, you can use window functions and union all:
select team_id,
sum(points = max_points) as num_wins,
sum(points < max_points) as num_losses,
sum(points = max_points) / nullif(sum(points < max_points), 0) as ratio
from ((select a.*, max(points) over (partition by game_id) as max_points
from sport_a a
) union all
(select b.*, max(points) over (partition by game_id) as max_points
from sport_b b
)
) ab
group by team_id
Made a small edit ^
Related
So I have these 2 tables. I need to get whatever is in the 1st row, 3rd column of Table 1 (in this case, ducks) and insert it into Table 2, 1st row, 6th column (marked [here])
table 1 (teams)
PK
team_id groupno tname oname onumber oemail group series
1 1 ducks laura 123 a#b.com A 1
2 2 birds john 456 c#d.com A 1
3 3 redds hanna 789 e#f.com A 1
4 4 blues mark 102 g#h.com A 1
team_id and groupno while look the same, groupno goes up to 10 (counting all teams in a group), team_id goes on
table 2 (games)
PK
game_id match_id time field group team1 team2 series
1 1 0900 1 A [here] N/A 1
2 2 0930 1 A N/A N/A 1
3 3 1000 1 A N/A N/A 1
4 4 1030 1 A N/A N/A 1
game_id and match_id arent's the same, math_id goes up to 36 (It counts all the games played in single series), game_id goes on
Below what I've been working with
UPDATE games INNER JOIN teams
ON games.game_id = 1
SET games.team2 = teams.tname
WHERE teams.series=1;
What I want the result to be
Example:
vs 2. --- 3. vs 4.
vs 3. --- 2. vs 4.
vs 4. --- 2. vs 3.
It should take the names from table 1 and arranges them into game slots so each team plays against each other
PK
game_id match_id time field group team1 team2 series
1 1 0900 1 A ducks birds 1
2 2 0930 1 A reds blues 1
3 3 1000 1 A ducks reds 1
4 4 1030 1 A birds blues 1
5 5 1100 1 A ducks blues 1
6 6 1130 1 A reds birds 1
I think this should match every combination and put it in the game order:
UPDATE games g
INNER JOIN (
SELECT
(#cnt := #cnt + 1) game_id, t.team1, t.team2
FROM (
SELECT
DISTINCT t1.tname team1, t2.tname team2
FROM teams t1
CROSS JOIN (SELECT DISTINCT tname FROM teams) t2
WHERE t1.tname <> t2.tname
) t
CROSS JOIN (SELECT #cnt := 0) c
) mt ON mt.game_id = g.game_id
SET g.team1 = mt.team1,
g.team2 = mt.team2
;
though I'd recommend using team ids instead of team names.
If you mean ids then:
UPDATE table2 ti
SET ti.item2 = (SELECT t1.item FROM table1 t1 WHERE t1.id = 3)
WHERE ti.id = 1
;
I would like to display the highest score player after several rounds.
Here is the table:
PlayerID Round number of score
1 1 4
2 1 5
3 1 8
1 2 3
2 2 10
3 2 7
Expected Output
PlayerID number of score
2 15
3 15
I have tried this code, but here is error. How can I display the output?
SELECT playerID , MAX(SUM(numberOfGoals)) FROM Game;
TRY THIS:
SELECT playerID, SUM(numberOfGoals) AS numberOfGoals
FROM Game
GROUP BY playerID
HAVING SUM(numberOfGoals) IN (SELECT MAX(goals) FROM (SELECT SUM(numberOfGoals) goals
FROM Game GROUP BY playerID) t)
SELECT playerId, Sum(numberofscore)
FROM Game
Group By PlayerId
Order By Sum(numberofscore) Desc
I have a "resources" table that contains information about how resources of a specific weight are placed inside a territory by an user.
territory_id user_id weight
1 1 1
1 1 4
1 1 2
1 2 2
2 3 2
2 2 3
2 2 3
3 1 1
4 1 1
4 1 1
4 2 2
4 3 3
4 3 1
4 3 2
5 3 2
5 3 3
5 2 1
4 3 1
I want to calculate, for each existing territory, which user has the highest total weight of resources (and what is this value).
So this should be an expected outcome for the previous data:
territory_id best_user_id best_user_total_weight_of_resources
1 1 7
2 2 6
3 1 1
4 3 6
5 3 5
I have already tried several nested queries with SUM, MAX, GROUP BY but I really didn't find the proper way to calculate this.
I have found a lot of similiar question, but not solving this exact problem.
Any help? Thanks in advance!
EDIT:
I found out right now that the double GROUP BY (i.e. "GROUP BY territory_id, user_id") with double ORDER BY partially solves my problem, but it shows also information that I don't want (not only the best user, but each single user that placed at least one resource).
SELECT territory_id, user_id AS best_user_id, SUM( weight ) AS best_user_total_weight
FROM resources
GROUP BY territory_id, user_id
ORDER BY territory_id ASC, best_user_total_weight DESC;
You can run a first query to determine SUM(weight) for each couple (territory_id,user_id) and then run a second SELECT query on that result set to retrieve the row corresponding to max summ value:
SELECT territory_id, user_id, MAX(summ)
FROM (
SELECT territory_id, user_id, SUM(weight) AS summ
FROM resources
GROUP BY territory_id, user_id
) AS t1
GROUP BY territory_id
I have a table with winner and loser statistics from a game:
id winner_id loser_id
1 1 2
2 1 2
3 3 4
4 4 3
5 1 2
6 2 1
7 3 4
8 3 2
9 3 5
10 3 6
11 2 3
12 3 6
13 2 3
I want a result table where i can find the highest winning streak of every player in the game. A streak of a player is broken, when he lost a game (player_id = loser_id). It should look like:
player_id win_streak
1 3
2 2
3 4
4 1
5 0
6 0
I tried many queries with user defined variables etc. but i can't find a solution. Thanks!
SQL Fiddle : http://sqlfiddle.com/#!9/3da5f/1
Is this the same as Alex's approach; I'm not quite sure, except that it seems to have one distinct advantage.... ;-)
SELECT player_id, MAX(CASE WHEN result = 'winner' THEN running ELSE 0 END) streak
FROM
( SELECT *
, IF(player_id = #prev_player,IF(result=#prev_result,#i:=#i+1,#i:=1),#i:=1) running
, #prev_result := result
, #prev_player:=player_id
FROM
( SELECT id, 'winner' result, winner_id player_id FROM my_table
UNION
SELECT id, 'loser', loser_id FROM my_table
) x
,
( SELECT #i:=1,#prev_result = '',#prev_player:='' ) vars
ORDER
BY x.player_id
, x.id
) a
GROUP
BY player_id;
I guess you should better to do that on php (or any other language you use) side.
But just to give you some idea and as experiment and example for some unique cases (hope it could be useful somewhere)
Here is my approach:
http://sqlfiddle.com/#!9/57cc65/1
SELECT r.winner_id,
(SELECT MAX(IF(winner_id=r.winner_id,IF(#i IS NULL, #i:=1,#i:=#i+1), IF(loser_id = r.winner_id, #i:=0,0)))
FROM Results r1
WHERE r1.winner_id = r.winner_id
OR r1.loser_id = r.winner_id
GROUP BY IF(winner_id=r.winner_id, winner_id,loser_id)) win_streak
FROM ( SELECT winner_id
FROM Results
GROUP BY winner_id
) r
It returns not all ids now but only who had ever win. So to make it better, probably you have user table. If so it would simplify a query. If you have no user table you need to union all somehow users who had never win.
You are welcome if any questions.
If my data is this
match homeTeam awayTeam homeTeamID awayTeamID homePoints awayPoints
1 Alpha Beta 1 2 4 2
2 Gamma Delta 3 4 6 0
3 Alpha Gamma 1 3 2 4
4 Delta Beta 4 2 3 3
I need to make a ladder for them but I can't get it just right
The results should look like this
Name played Points
Gamma 2 10
Alpha 2 6
Beta 2 5
Delta 2 3
So far my code looks like this
$query = "SELECT *
FROM (
SELECT homeTeam AS teamName,
COUNT(homeTeamID) AS matches_played,
SUM(if(homeTeamID, homePoints, 0)) AS total_points
FROM matches
UNION ALL SELECT awayTeam AS teamName,
COUNT(awayTeamID) AS matches_played,
SUM(if(awayTeamID, awayPoints, 0)) AS total_points
FROM matches
) all_points
GROUP BY teamName
ORDER BY total_points DESC ";
but all it did was show ALPHA played 4 games for 15 points and BETA played 4 games for 9 points - Gamma & Delta were gone :(
You do not have GROUP BY clause in inner query.
But it's still incorrect. try:
SELECT teamName, COUNT(*) AS played, SUM(points) as points
FROM (
SELECT homeTeam AS teamName,
homePoints AS points
FROM matches
UNION ALL SELECT awayTeam AS teamName,
awayPoints AS points
FROM matches
) all_points
GROUP BY teamName
ORDER BY total_points DESC