这段代码和预期的一样好用,但是它很长而且令人毛骨悚然。
select p.name, p.played, w.won, l.lost from
(select users.name, count(games.name) as played
from users
inner join games on games.player_1_id = users.id
where games.winner_id > 0
group by users.name
union
select users.name, count(games.name) as played
from users
inner join games on games.player_2_id = users.id
where games.winner_id > 0
group by users.name) as p
inner join
(select users.name, count(games.name) as won
from users
inner join games on games.player_1_id = users.id
where games.winner_id = users.id
group by users.name
union
select users.name, count(games.name) as won
from users
inner join games on games.player_2_id = users.id
where games.winner_id = users.id
group by users.name) as w on p.name = w.name
inner join
(select users.name, count(games.name) as lost
from users
inner join games on games.player_1_id = users.id
where games.winner_id != users.id
group by users.name
union
select users.name, count(games.name) as lost
from users
inner join games on games.player_2_id = users.id
where games.winner_id != users.id
group by users.name) as l on l.name = p.name
如您所见,它由3个重复的检索部分组成:
- 玩家姓名和他们玩的游戏数量
- 玩家姓名和他们赢得的游戏数量
- 玩家姓名和他们输掉的游戏数量
每一个都由两部分组成:
- 玩家姓名和他们作为player_1参与的游戏数量
- 玩家姓名和他们作为player_2参与的游戏数量
这怎么能简单呢?
结果看起来是这样的:
name | played | won | lost
---------------------------+--------+-----+------
player_a | 5 | 2 | 3
player_b | 3 | 2 | 1
player_c | 2 | 1 | 1
3条答案
按热度按时间sg24os4d1#
Postgres 9.4或更高版本中的标准SQL聚合
FILTER
子句更短、更快:在Postgres 9.3(或 * 任何 * 版本)中,这仍然比嵌套的子选择或
CASE
表达式更短、更快:请参阅:
4xrmg8kj2#
在这种情况下,相关子查询可以简化逻辑:
这是假设没有连接。
nimxete23#