I'm trying to aggregate depending on the conditional if player_id (Gary)
has greater, equal, or less score then player_id("other")
my schema has
players(player_id, name)
matches(match_id, home_team(player_id), away_team(player_id) )
outcome(outcome_id, match_id, home_score:integer, away_score:integer
Output from:
select m.match_id, p.name AS home_team, p1.name AS away_team, o.home_score, o.away_score
from players p
inner join matches m on (p.player_id = m.home_team)
inner join players p1 on (p1.player_id = m.away_team)
inner join outcomes o on (m.match_id = o.match_id);
match_id | player_id | player_id | home_score | away_score
----------+-----------+-----------+------------+------------
1 | 1 | 2 | 1 | 2
2 | 2 | 1 | 1 | 3
3 | 3 | 1 | 3 | 2
Wanted output:
player_id | Wins | Draws | Losses
-------------+------+-------+--------
1 | 1 | 0 | 2
2 ... | ... | .. | ...
My schema are open for alteration.
EDIT(sqlfiddle): http://www.sqlfiddle.com/#!2/7b6c8/1
I would use UNION ALL to get every outcome twice, once for home and once for away player. The second time home_score/away_score should be switched, to get correct sums for away player.
select
d.player_id,
d.name,
sum(d.home_score > d.away_score) as wins,
sum(d.home_score = d.away_score) as draws,
sum(d.home_score < d.away_score) as loses
from (
select p.player_id, p.name, o.home_score, o.away_score
from players p
join matches m on p.player_id = m.home_team
join outcomes o on o.match_id = m.match_id
union all
select p.player_id, p.name, o.away_score as home_score, o.home_score as away_score
from players p
join matches m on p.player_id = m.away_team
join outcomes o on o.match_id = m.match_id) d
group by d.player_id, d.name
Returns:
PLAYER_ID NAME WINS DRAWS LOSES
1 Gary 1 0 2
2 Tom 1 0 1
3 Brad 1 0 0
sqlFiddle demo: http://www.sqlfiddle.com/#!2/7b6c8/21
For a solution without a subquery and unions: http://www.sqlfiddle.com/#!2/7b6c8/31
SELECT
p.player_id,
COALESCE(SUM(o1.home_score > o1.away_score or o2.home_score < o2.away_score), 0) wins,
COALESCE(SUM(o1.home_score = o1.away_score or o2.home_score = o2.away_score), 0) draws,
COALESCE(SUM(o1.home_score < o1.away_score or o2.home_score > o2.away_score), 0) losses
FROM players p
LEFT JOIN matches m1 ON (p.player_id = m1.home_team)
LEFT JOIN players p1 ON (p1.player_id = m1.away_team)
LEFT JOIN outcomes o1 ON (m1.match_id = o1.match_id)
LEFT JOIN matches m2 ON (p.player_id = m2.away_team)
LEFT JOIN players p2 ON (p2.player_id = m2.home_team)
LEFT JOIN outcomes o2 ON (m2.match_id = o2.match_id)
GROUP BY p.player_id
Results:
PLAYER_ID WINS DRAWS LOSSES
1 1 0 2
2 1 0 1
3 1 0 0
4 0 0 0
5 0 0 0
Related
I have 2 tables:
Players
ID
Name
1
John
2
Maya
3
Carl
Results
ID
Player_ID
Result
1
1
250
2
1
300
3
2
100
4
2
350
5
3
500
I want to select all the names from the table Players and the top scores of each person.
What I have so far:
SELECT Players.Name, max(Results.Result)
FROM Players JOIN Results
WHERE Players.ID = Results.Player_ID
But this only selects
| Carl | 500 |
and I want
| John | 300 |
| Maya | 350 |
| Carl | 500 |
try with a condition on the result : it needs to be the highest (max) for the player ID.
Try this:
SELECT p.Name, r.result FROM Players p JOIN Results r WHERE p.ID = r.Player_ID and r.result = (select max(result) from results rr where rr.Player_ID = p.ID)
You need to GROUP BY Players.ID, Players.Name to your query. I added Players.ID in case two players have the same name:
SELECT Players.Name, max(Results.Result)
FROM Players JOIN Results
WHERE Players.ID = Results.Player_ID
GROUP BY Players.ID, Players.Name
i have 2 tables like below:
lk_premier:
code descr
P Premier
N Non Premier
Case:
id taxPin
1 123
2 789
Status:
id voting_status premier
1 5 P
1 5 P
1 5 P
2 5 P
2 5 N
2 5 null
3 5 null
3 5 null
3 5 null
3 5 null
3 5 null
I used the below sql
select
decode(premier,
'P',
'PREMIER',
'N',
'NON PREMIER') as caseStatus,
count(*) as count
from
status s,
case c
where
c.id = s.id
and c.id = 1
and s.voting_status = 5
group by
premier
I want to join the lk_premier table, so my output looks like for id=2,
caseStatus count
PREMIER 1
NON PREMIER 1
for id = 3
caseStatus count
PREMIER 0
NON PREMIER 0
You should never do joins this way -- this way of doing joins was depreciated about 20 years ago. the join should look like this:
join status s on c.id = s.id
once you do joins the right way then how you do left joins is easier as seen below:
here you go
select
coalesce(p.desc,'unknown') as caseStatus,
count(*) as count
from case c
join status s on c.id = s.id
left join lk_premier p on p.code = c.premier
where c.id = 1 and s.voting_status = 5
group by coalesce(p.desc,'unknown')
Need a help with sql query.
I have 2 tables.
Matches.
first_referee_arbitr_id
second_referee_arbitr_id
home_team
guest_team
date
Arbitrs.
id
name
surname
first_referee_arbitr_id and second_referee_arbitr_id are from Arbitrs table(id).
As the result I need to count how much each referee has been included in matches:
referee_first_count | referee_second_count | Arbitr Surname | Arbitr Name
My query now:
SELECT T1.referee_first_count, T2.referee_second_count, T1.surname, T1.name
FROM (
select matches.first_referee_arbitr_id, q.surname, q.name, count(*) AS referee_first_count
FROM matches
JOIN (
SELECT name, surname, id
FROM arbitrs
) as q ON matches.first_referee_arbitr_id=q.id
GROUP BY matches.first_referee_arbitr_id, q.name, q.surname
ORDER BY referee_first_count DESC
) T1 FULL OUTER JOIN
(
select matches.second_referee_arbitr_id, arbitr.surname, arbitr.name, count(*) AS referee_second_count
FROM matches
JOIN (
SELECT name, surname, id
FROM arbitrs
) as arbitr ON matches.second_referee_arbitr_id=arbitr.id
GROUP BY matches.second_referee_arbitr_id, arbitr.name, arbitr.surname
ORDER BY referee_second_count DESC
) T2
ON (
(T1.name = T2.name) AND (T1.surname = T2.surname)
)
Example
Arbitrs:
id | Name | Surname
1 John Rambler
2 Steve Crystler
3 Tom Ferguson
Matches:
first_referee_arbitr_id| second_referee_arbitr_id| home_team | guest_team | date
1 Chelsea Everton 22.06.2020
2 1 Liverpool Lester 28.06.2020
3 Dinamo K Dinamo M 06.07.2020
1 2 Juventus Dinamo K 10.10.2020
3 Dinamo K Chelsea 20.20.2020
Result:
referee_first_count | referee_second_count | surname | name
2 1 Rambler John
1 1 Crystler Steve
2 0 Ferguson Tom
My result now with query above:
referee_first_count | referee_second_count | surname | name
2 1 Rambler John
1 1 Crystler Steve
2 NULL NULL NULL
First aggregate the matches table (twice) and left join this to the Arbitrs table:
SELECT a.name , a.Surname , ISNULL(fir.first_count,0) , ISNULL( sec.sec_count,0)
FROM Arbitrs a
LEFT JOIN (
SELECT first_referee_arbitr_id,COUNT(*) as first_count
FROM Matches
GROUP BY first_referee_arbitr_id
) fir
ON fir.first_referee_arbitr_id = a.id
LEFT JOIN (
SELECT second_referee_arbitr_id,COUNT(*) as sec_count
FROM Matches
GROUP BY second_referee_arbitr_id
) sec
ON sec.second_referee_arbitr_id = a.id
SELECT
a.name
, a.surname
, COUNT(CASE WHEN m1.id IS NOT NULL THEN 1 end) referee_first_count
, COUNT(CASE WHEN m2.id IS NOT NULL THEN 1 end) referee_second_count
FROM
Arbitrs a
LEFT JOIN macthes m1
ON a.id = m.first_referee_arbitr_id
LEFT JOIN macthes m2
ON a2.id = m.second_referee_arbitr_id
GROUP BY
a.name
, a.surname
-- if you want to show only those with refrence
HAVING referee_first_count > 0 or referee_second_count > 0
My query
with with_user_earns as (
-- get father information (start)
select father.id, father.str_name, father.id_father, father.ind_father_side_type, 1 as int_user_level from tb_user father where id = #v_user_id
union all
-- get son information (stop condition)
select son.id, son.str_name, son.id_father, son.ind_father_side_type, WUE.int_user_level + 1
from tb_user as son inner join with_user_earns as WUE on son.id_father = WUE.id
where son.id_father is not null and WUE.int_user_level < #v_max_level
)
select aux.*
from (
-- show result
select with_user_earns.id id_son, with_user_earns.str_name str_son_name, with_user_earns.id_father, father.str_name str_father_name, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, isnull(sum(o.int_score), 0) as int_score
from with_user_earns inner join tb_order o on o.id_user = with_user_earns.id
inner join tb_user as father on father.id = with_user_earns.id_father
where o.dt_insert between #v_cycle_begin and #v_cycle_end and o.ind_payment_status = 3
group by with_user_earns.id, with_user_earns.str_name, with_user_earns.id_father, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, father.str_name
) as aux
order by aux.int_user_level, aux.id_son
The table with_user_earns contains a lot of users (mult nivel hierarchy).
Then I want to join with tb_order to get int_score 0 if the user sell nothing and if the user sell anything I want the sum of it.
I tried put left join, full outer join, ... But no one works perfect
What a need to do?
My result:
id_son int_score
1 100
2 11100
3 100
10 300
Expected result:
id_son int_score
1 100
2 11100
3 100
4 0
5 0
6 0
7 0
8 0
9 0
10 300
I have an unresolved doubt about a query I'm making in PostgreSQL.
I have these 2 tables
PLAYER
playerID title
1 Rondo
2 Allen
3 Pierce
4 Garnett
5 Perkins<
PLAYS
playerID TeamID
1 1
1 2
1 3
2 1
2 3
3 1
3 3
and that's my query
SELECT DISTINCT concat(N.playerID, ':', N.title), TID
FROM player N
INNER JOIN (
SELECT DISTINCT P.playerID as PID, teamID as TID
FROM plays P
) AS derivedTable
ON N.playerID = PID
ORDER BY concat
the result of the query is:
"1:Rondo" | 1
"1:Rondo" | 2
"1:Rondo" | 3
"2:Allen" | 1
"2:Allen" | 3
"3:Pierce" | 1
"3:Pierce" | 3
but I want something like that
"1:Rondo" | 1, 2, 3
"2:Allen" | 1, 3
"3:Pierce" | 1, 3
I could use an array_agg, but i really dunno how
Use string_agg()
SELECT concat(N.playerID, ':', N.title),
string_agg(p.TeamID::text, ',') as teamid_list
FROM player N
JOIN plays p ON n.playerID = p.playerID
GROUP BY n.playerID, n.title
ORDER BY 1;
Your derived table is not necessary (and the distinct even more so)
In Postgres should be:
SELECT concat(N.playerID, ':', N.title) title, string_agg(P.TID,', ') TID
FROM player N
LEFT JOIN plays P ON N.playerID = P.PID
GROUP BY 1
ORDER BY 1
For MySQL
Try this:
SELECT CONCAT(N.playerID, ':', N.title) playerTitle,
GROUP_CONCAT(P.TID SEPARATOR ', ') TID
FROM player N
LEFT JOIN plays P ON N.playerID = PID
GROUP BY N.playerID
ORDER BY playerTitle