所以我有两个表,球员和比赛结构如下:
Table "public.players"
Column | Type | Modifiers
--------+---------+------------------------------------------------------
id | integer | not null default nextval('players_id_seq'::regclass)
name | text |
wins | integer | default 0
loses | integer | default 0
rating | integer | default 1500
和
Table "public.matches"
Column | Type | Modifiers
---------------+---------+------------------------------------------------------
id | integer | not null default nextval('matches_id_seq'::regclass)
player1 | integer |
player1rating | integer |
player2 | integer |
player2rating | integer |
winner | boolean |
如果获胜者是真的,如果球员1赢得那场比赛,那么如果球员2赢得那场比赛则为假。
使用球员表进行简单的赢/输比较很容易,但是我正在观察两位球员相互面对的比较,他们彼此之间的记录是什么。
所以我很困惑我如何总结给定玩家可能被列为player1或player2的条件: P1赢了:
(player1 = <player1> AND winner = true) OR (player2 = <player1> AND winner = false)
P2胜利:
(player1 = <player2> AND winner = true) OR (player2 = <player2> AND winner = false)
损失将与其他球员的胜利相反。
返回信息的内容如下:
id | name | wins | loses | rating | wins_v_opp | loses_v_opp
------+----------+------+-------+--------+------------+------------
4200 | Sinku | 5 | 48 | 1191 | 1 | 4
4201 | Kenshiro | 33 | 29 | 1620 | 4 | 1
我在下面的update2之前想出了什么:
CREATE FUNCTION matchup(text, text) AS $$
DECLARE
player1_name ALIAS FOR $1;
player2_name ALIAS FOR $2;
BEGIN
EXECUTE 'SELECT id FROM player WHERE name LIKE $1'
INTO player1_id
USING player1_name;
IF NOT FOUND THEN
RAISE EXCEPTION 'Player1 % not found', player1_name;
END IF;
EXECUTE 'SELECT id FROM player WHERE name LIKE $1'
INTO player2_id
USING player2_name;
IF NOT FOUND THEN
RAISE EXCEPTION 'Player2 % not found', player2_name;
END IF;
RETURN QUERY EXECUTE 'WITH cte_winners AS (
SELECT
CASE WHEN winner THEN m.player1 ELSE m.player2 END AS player,
COUNT(*) AS wins_v_opp,
sum(count(*)) over() - COUNT(*) AS loses_v_opp
FROM matches AS m
WHERE player1 IN ($1,$2) AND player2 IN ($1,$2)
GROUP BY player
)
SELECT * FROM players AS p
LEFT OUTER JOIN cte_winners AS cw ON cw.player = p.id WHERE p.id IN ($1,$2)'
USING player1_id,player2_id;
END;
$$ LANGUAGE plpgsql;
答案 0 :(得分:1)
如果您想选择<player1>
或<player2>
赢得的匹配,您可以使用此查询:
with cte_winners as (
select
id, case when winner then player1 else player2 end as player
from public.matches
)
select *
from cte_winners
where player in (<player1>, <player2>)
<强>更新强>
获得所需的输出你可以使用这样的东西:
with cte_winners as (
select
case when winner then m.player1 else m.player2 end as player,
count(*) as wins_v_opp,
sum(count(*)) over() - count(*) as loses_v_opp
from matches as m
where player1 in (4200, 4201) and player2 in (4200, 4201)
group by player
)
select *
from players as p
left outer join cte_winners as cw on cw.player = p.id
where p.id in (4200, 4201)
<强> sql fiddle demo 强>
<强> UPDATE2 强>
with cte_player as (
select p.id, p.name, p.wins, p.losses, p.rating
from players as p
where p.name in ('Sinku', 'Kenshiro')
), cte_winner as (
select
case when winner then m.player1 else m.player2 end as player,
count(*) as wins_v_opp,
sum(count(*)) over() - count(*) as loses_v_opp
from matches as m
where
m.player1 in (select p.id from cte_player as p) and
m.player2 in (select p.id from cte_player as p)
group by player
)
select
p.id, p.name, p.wins, p.losses, p.rating,
m.wins_v_opp, m.loses_v_opp
from cte_player as p
left outer join cte_winner as m on m.player = p.id
<强> sql fiddle demo 强>
答案 1 :(得分:1)
SELECT id, name, wins, losses, rating
,count(CASE WHEN winner THEN m.player1 = p.id ELSE m.player2 = p.id END
OR NULL) AS wins_v_opp
,count(CASE WHEN winner THEN m.player2 = p.id ELSE m.player1 = p.id END
OR NULL) AS loses_v_opp
FROM (
SELECT *, COALESCE(lag(p.id) OVER(), lead(p.id) OVER()) AS id2
FROM players p
WHERE p.name in ('Sinku', 'Kenshiro')
) p
JOIN matches m ON m.player1 IN (id, id2)
AND m.player2 IN (id, id2)
GROUP BY 1,2,3,4,5;
- &GT; SQLfiddle
答案 2 :(得分:0)
select id
from public.matches
where player1 in ('<player1's number>','<player2's number>')
and player2 in ('<player1's number>','<player2's number>')
应该返回他们互相比赛的所有比赛和
select id
from public.matches
where (player1 = '<player1's number>' or player2 = '<player1's number>')
and (player1 = '<player2's number>' or player2 = '<player2's number>')
and winner = <condition that shows player1's wins>
返回假想的玩家1赢得的与假设玩家2的匹配。
因此获得评级看起来像
select ((
select count(distinct id)
from public.matches
where (player1 = '<player1's number>' or player2 = '<player1's number>')
and (player1 = '<player2's number>' or player2 = '<player2's number>')
and winner = <condition that shows player1's wins>
) / (
select id
from public.matches
where player1 in ('<player1's number>','<player2's number>')
and player2 in ('<player1's number>','<player2's number>')
) * 100) as percent_of_player1_wins
from dual
请注意我使用的是PLSQL语法。