【问题标题】:Find all the luckest players from the history table using one nested query使用一个嵌套查询从历史表中查找所有最幸运的玩家
【发布时间】:2021-01-25 17:33:41
【问题描述】:

我们如何将两个查询组合成一个嵌套查询。假设我们有一个名为 history 的游戏关系,其中 history: playerid (string), roldid (string), Directions(string), year (integer), dice (integer)。

添加了更多约束,但最初的问题是用一种工作方法回答的,但如果你知道如何在没有 rank() 的情况下做到这一点。请分享。试图从根本上

playerid    roldid     direct       year        dice     
p01         panda       W           2013        6         
p02         bird        N           2014        6         
p03         monkey      S           2013        1         
p01         dog         E           2015        6
p03         monkey      S           2015        4         
p02         cat         S           2015        6         
p04         cat         S           2015        2         
p05         fish        W           2015        4

假设我们想要一个返回的嵌套查询:

p01         6       
p02         6

由于在整个游戏过程中,p01 和 p02 掷骰子时总是得到 6。

我知道如何在两个查询中执行此操作,但需要创建一个嵌套查询。 两个查询:

select playerid, sum(dice)/count(*) from history group by playerid;

返回:

playerid    sum(dice)/count(*)
p01         6       
p02         6
p03         2.5
p04         2
p05         4

然后我们可以让另一个查询返回所有 Max s,在这种情况下恰好是 6,但它可能是 p01,p03 都是 4.6 是 Max

我尝试过的 max(sum(dice)/count(*)) 不起作用。任何建议。

【问题讨论】:

  • 只标记您使用的数据库

标签: sql database sqlite nested


【解决方案1】:

如果你想要只扔 6 个的玩家,你可以使用聚合:

select h.playerid
from history h
group by h.playerid
having min(dice) = max(dice) and min(dice) = 6;

【讨论】:

  • 如果最幸运的是 4.5 或 5.4 或 5.9 怎么办?提前知道6个是不切实际的。谢谢
  • @Maxfield 。 . .这回答了您提出的问题,该问题似乎与“6”有关。这个问题没有定义“最幸运”。
【解决方案2】:

您可以使用group by和解析函数如下:

Select * from
(select playerid, sum(dice)/count(*) as ratio_,
        rank() over (partition by playerid order by sum(dice)/count(*) desc) as rn
 from history 
group by playerid) t
Where rn = 1

即使骰子一直不是 6,这也会返回最幸运的人。

【讨论】:

  • Select * from (select playerid, sum(dice)/count() as ratio_rank() over (partitiin by playerid order by sum(dice)/count() desc) as rn from history group by playerid) t where rn = 1. Error: near "rank": syntax error
  • 这将在这种情况下起作用,因为您可以看到我的答案中没有使用硬代码 6。
  • 是的。我的意思是评论其他帮助。谢谢。
  • 是的,ratio_ 后面缺少逗号 (,)。更新了答案。请立即检查。
【解决方案3】:

您可以使用AVG() 聚合函数和RANK() 窗口函数:

SELECT playerid, avg_dice
FROM (
  SELECT playerid, 
         AVG(dice) avg_dice,
         RANK() OVER (ORDER BY AVG(dice) DESC) rnk
  FROM history
  GROUP BY playerid
)
WHERE rnk = 1 

另一种不使用窗口函数的方法,使用HAVING 子句:

SELECT playerid, 
       AVG(dice) avg_dice
FROM history
GROUP BY playerid
HAVING avg_dice = (SELECT AVG(dice) FROM history GROUP BY playerid ORDER BY AVG(dice) DESC LIMIT 1)

请参阅demo
结果:

playerid avg_dice
p01 6
p02 6

【讨论】:

  • 你能解释一下吗?因为它确实有效,但请帮助我更好地理解。
  • 子查询计算dice 列的平均值,每个玩家的AVG(dice) 并按该平均值降序排列每个玩家。这是通过窗口函数 RANK() 完成的。最后,从子查询返回的所有行中,仅返回 rank = 1 的行。
  • 您能解释一下为什么添加限制 1。它对我的数据集没有影响,但想知道您为什么添加它。
  • @Maxfield 子查询:(SELECT AVG(dice) FROM history GROUP BY playerid ORDER BY AVG(dice)) 没有 LIMIT 1 返回所有 playerid 的所有平均值。您只想将最高平均值与avg_dice 进行比较,这就是我使用 LIMIT 1 的原因,这也是在标准 SQL 中应该如何完成的。但是 SQLite 有一个特殊的 feature,在这种情况下,它只比较没有 LIMIT 1 的顶行。任何其他数据库都会抛出错误。你可以在这里找到更多:sqlite.org/lang_expr.html#subquery_expressions
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
相关资源
最近更新 更多