【问题标题】:aggregation with conditionals?用条件聚合?
【发布时间】:2013-12-08 23:35:45
【问题描述】:

我正在尝试根据条件 if player_id (Gary) 进行聚合 得分大于、等于或小于 player_id("other")

我的架构有

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

输出来自:

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

想要的输出:

 player_id   | Wins | Draws | Losses
-------------+------+-------+--------
  1          |    1 |    0  |    2
  2    ...   | ...  |    .. |    ...

我的架构可以更改。

编辑(sqlfiddle):http://www.sqlfiddle.com/#!2/7b6c8/1

【问题讨论】:

  • 啊,很抱歉模棱两可,没关系!重点更多地放在每个玩家@Filipe Silva 的获胜次数和平局数上
  • 您可以在原始表格示例数据中添加sqlfiddle 吗?
  • 会的! @FilipeSilva

标签: sql postgresql database-schema


【解决方案1】:

我会使用UNION ALL 来获取每个outcome 两次,一次用于home,一次用于away 玩家。第二次应该切换home_score/away_score,以获得away玩家的正确总和。

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

返回:

PLAYER_ID   NAME    WINS    DRAWS   LOSES
1           Gary    1       0       2
2           Tom     1       0       1
3           Brad    1       0       0

sqlFiddle 演示:http://www.sqlfiddle.com/#!2/7b6c8/21

【讨论】:

  • 非常感谢!尽管我不知道我的架构是否正确设置以回答此类查询,但这对我有很大帮助并得到了预期的结果! @MarcinJuraszek
【解决方案2】:

对于没有子查询和联合的解决方案: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    

结果:

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

【讨论】:

  • 恐怕这不会按预期返回结果,它应该是 Marcin 的回答 @Wolph
  • 确实,我忘记了反向关系:) 我添加了一个修改版本。我个人不是联盟所有方法的粉丝
  • 啊,太好了!感谢您提供的解决方案,我从这两个示例中学到了很多东西!我也想将您的答案作为解决方案,但马辛“更快”地解决了它,在生产中我想我会和你一起去@Wolph
猜你喜欢
  • 1970-01-01
  • 2020-02-27
  • 2021-08-24
  • 2019-08-13
  • 2010-11-01
  • 1970-01-01
  • 2014-06-08
  • 2015-08-17
  • 2019-11-17
相关资源
最近更新 更多