当前位置: 首页 > 面试题库 >

汇总带有其他(不同)过滤器的列

谷梁镜
2023-03-14
问题内容

这段代码可以正常工作,但是我又长又令人毛骨悚然。

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个重复部分组成,用于检索:

  • 玩家名称和他们玩过的游戏数量
  • 玩家名称和他们赢得的游戏数量
  • 玩家姓名和输掉的游戏数量

并且每个还包括2个部分:

  • 玩家名称和以玩家_1身份参加的游戏数量
  • 玩家名称以及他们作为玩家_2参加的游戏数量

如何简化呢?

结果看起来像这样:

           name            | played | won | lost 
---------------------------+--------+-----+------
 player_a                  |      5 |   2 |    3
 player_b                  |      3 |   2 |    1
 player_c                  |      2 |   1 |    1

问题答案:

Postgres 9.4* 或更高版本中的 聚合FILTER子句越来越短: *

SELECT u.name
     , count(*) FILTER (WHERE g.winner_id  > 0)    AS played
     , count(*) FILTER (WHERE g.winner_id  = u.id) AS won
     , count(*) FILTER (WHERE g.winner_id <> u.id) AS lost
FROM   games g
JOIN   users u ON u.id IN (g.player_1_id, g.player_2_id)
GROUP  BY u.name;

在Postgres 9.3 (或 任何 版本)中,它仍然比嵌套的子选择或CASE表达式短和快:

SELECT u.name
     , count(g.winner_id  > 0 OR NULL)    AS played
     , count(g.winner_id  = u.id OR NULL) AS won
     , count(g.winner_id <> u.id OR NULL) AS lost
FROM   games g
JOIN   users u ON u.id IN (g.player_1_id, g.player_2_id)
GROUP  BY u.name;

细节:

  • 为了获得绝对的性能,SUM是更快还是COUNT?


 类似资料:
  • 我有一个包含以下数据的pyspark dataframe:

  • 问题内容: 我正在尝试将换行符()转换为html 。 根据Google网上论坛的讨论,这是我得到的: 那里的讨论还建议在视图中使用以下内容: 这似乎正在使用旧的过滤器,而现在我们应该使用属性。 无论如何,这都会带来一个问题:我不希望原始字符串()中的任何HTML 都呈现为HTML;只有的。 例如,给定以下字符串: 虽然7> 5,但 我仍然不希望html和其他东西出现在这里… 我希望它输出: 有什么

  • 问题内容: SQL查询是否可以返回一些常规列和一些聚合列? 喜欢 : 问题答案: 您应该使用group by语句。 GROUP BY语句与聚合函数结合使用,以按一个或多个列对结果集进行分组。 例如: 您可以在此处看到完整的示例。

  • 问题内容: 我在elasticsearch中拥有大型文档存储,并希望检索不同的过滤器值以显示在HTML下拉列表中。 一个例子是像 下拉列表应包含部门列表,即IT,客户和管理部门。 请问有什么好心的人向我指出正确的方向,以便从Elasticsearch检索不同的部门列表吗? 谢谢 问题答案: 这是聚合(文档)的工作。 您可以使用以下不同的值: 在您的示例中,输出: 另外两个注意事项: 设置为0会将最

  • 问题内容: 我正在尝试建立一个查询,该查询将找到所有用户文档(docType =用户),然后根据许多过滤器对其进行过滤。例如位置,性别,年龄等。过滤器是根据我正在构建的搜索功能上的用户输入来添加/删除的。 以下没有结果: 以下返回结果: 后者虽然返回结果,但从长远来看是行不通的,因为我可能想为年龄,性别等添加一个额外的过滤器,而且我似乎无法添加多个字段。如果我删除位置过滤器,则第一个查询有效。 问

  • 我试图建立MySQL查询与多个连接,其中加入的值的总和。有3个表:保管人,帐户和存款。账户和存款通过客户的customer_id字段连接到客户。在查询结束时,所有客户都按group_id分组: 问题是:连接的行重复,而我必须进行一些分析:汇总所有存款金额-您可以在这里看到我针对存款金额的解决方法。但真正的问题是如何计算“客户的首次存款”。在对结果进行分组之前,我们可能会看到: 所以,我需要的是总和