sql - 查找按其关系的聚合属性排序的实体
问题描述
Question 与 Find entity 非常相似,其中大多数关系都按条件过滤,但略有不同。
model Player {
id String @id
name String @unique
game Game[]
}
model Game {
id String @id
isWin Boolean
playerId String
player Player @relation(fields: [playerId], references: [id])
}
我想找到 10 名获胜率最高的玩家(游戏isWin=true
除以该玩家的游戏总数)。
直接而缓慢的方法是找到至少赢过一次的所有玩家并计算他们的胜利(第一次查询)。然后为他们每个人计算他们的游戏总数(第二个查询)。然后在应用程序端进行数学计算和排序,同时将结果保存在内存中。
有没有更简单的方法来做到这一点?我该怎么做prisma
呢?如果没有 prisma “本机”方式来做到这一点,那么使用原始 SQL 执行此操作的最有效方法是什么?
解决方案
这是简单的聚合:
SELECT p.id, p.name
, COUNT(CASE WHEN isWin THEN 1 END) AS wins
, COUNT(g.playerId) AS played
, 100 * COUNT(CASE WHEN isWin THEN 1 END)
/ COUNT(g.playerId) AS rate
FROM player AS p
JOIN game AS g
ON g.playerId = p.id
GROUP BY p.name -- since p.name is unique, not the id.
ORDER BY rate DESC
LIMIT 10
;
根据您的数据库的需要进行调整。我调整了连接变成左连接的情况,以处理没有玩过游戏的玩家。
PG 的可执行示例,如下面的评论所示。 工作测试用例 - 无数据
推荐阅读
- flutter - 颤振绘制clipPath
- sql - 如何使用当前行值为 column2 的所有行中的 column1 中的所有值的列表填充 PostgresQL 列
- aws-load-balancer - 可以在 Orocomerce 使用负载均衡器和 SSL 吗?
- django - 实现第一个序列化程序的 AttributeError:“QuerySet”对象没有属性“名称”
- javascript - 如何通过 ScriptManager.RegisterStartupScript 将特殊字符从 C# 传递到 JavaScript
- ios - 本地化并不总是适用于某些文本
- java - 通过单元测试测试服务方法?
- php - 获取名称而不是 ID
- mysql - Hibernate & MySQL:创建记录时,添加第二条记录并且完全为空
- python - 在 cmd 中找不到 Python 模块