显示游戏排名网格:优化左外连接并查找玩家

发布于 2024-08-29 20:48:40 字数 1302 浏览 7 评论 0原文

我想做一个排名网格。

我有一个表,其中包含由键索引的不同值:

表 SimpleValue :键 varchar,值 int,playerId int

我有一个具有多个 SimpleValue 的播放器。

表 Player: id int,nickname varchar

现在想象一下这些记录:

SimpleValue:

Key      value     playerId
for      1         1
int      2         1
agi      2         1
lvl      5         1

for      6         2
int      3         2
agi      1         2
lvl      4         2

Player:

id     nickname
1      Bob
2      John

我想在各种 SimpleValue 上显示这些玩家的排名。类似于:

nickname      for       lvl     
Bob           1         5       
John          6         4  

目前,我根据您想要显示的 SimpleValue 键以及您想要对玩家进行排序的 SimpleValue 键生成一个 sql 查询。

例如:我想显示每个玩家的“lvl”和“for”,并将它们按“lvl”排序

生成的查询是:

SELECT p.nickname as nickname, v1.value as lvl, v2.value as for
FROM Player p
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId and v1.key = 'lvl'
LEFT OUTER JOIN SimpleValue v2 ON p.id=v2.playerId and v2.key = 'for'
ORDER BY v1.value

此查询运行完美。但是如果我想显示 10 个不同的值,它会生成 10 个“左外连接”。有没有办法简化这个查询?

我有第二个问题:有没有办法显示此排名的一部分。假设我有 1000 名玩家,我想显示前 10 名,我使用 LIMIT 关键字。现在我想显示玩家 Bob 的排名,即 326/1000,并且我想显示上方和下方 5 个排名的玩家(即从 321 到 331 的位置)。我怎样才能实现它?

谢谢。

I want to do a ranking grid.

I have a table with different values indexed by a key:

Table SimpleValue : key varchar, value int, playerId int

I have a player which have several SimpleValue.

Table Player: id int, nickname varchar

Now imagine these records:

SimpleValue:

Key      value     playerId
for      1         1
int      2         1
agi      2         1
lvl      5         1

for      6         2
int      3         2
agi      1         2
lvl      4         2

Player:

id     nickname
1      Bob
2      John

I want to display a rank of these players on various SimpleValue. Something like:

nickname      for       lvl     
Bob           1         5       
John          6         4  

For the moment I generate an sql query based on which SimpleValue key you want to display and on which SimpleValue key you want to order players.

eg: I want to display 'lvl' and 'for' of each player and order them on the 'lvl'

The generated query is:

SELECT p.nickname as nickname, v1.value as lvl, v2.value as for
FROM Player p
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId and v1.key = 'lvl'
LEFT OUTER JOIN SimpleValue v2 ON p.id=v2.playerId and v2.key = 'for'
ORDER BY v1.value

This query runs perfectly. BUT if I want to display 10 different values, it generates 10 'left outer join'. Is there a way to simplify this query ?

I've got a second question: Is there a way to display a portion of this ranking. Imagine I've 1000 players and I want to display TOP 10, I use the LIMIT keyword. Now I want to display the rank of the player Bob which is 326/1000 and I want to display 5 rank player above and below (so from 321 to 331 position). How can I achieve it ?

thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

帅的被狗咬 2024-09-05 20:48:40

这称为“交叉表查询”。您可以使用像这样的条件求和语句 page

来获取:

SELECT p.nickname as nickname
, SUM(IF(key = "for", value,0)) AS `for`
, SUM(IF(key = "int", value,0)) AS `int`
, SUM(IF(key = "agi", value,0)) AS `agi`
, SUM(IF(key = "lvl", value,0)) AS `lvl`
FROM Player p
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId
GROUP By p.nickname
ORDER BY v1.value

This is called a "Crosstab query". You can use conditional sum statements like this page

To get:

SELECT p.nickname as nickname
, SUM(IF(key = "for", value,0)) AS `for`
, SUM(IF(key = "int", value,0)) AS `int`
, SUM(IF(key = "agi", value,0)) AS `agi`
, SUM(IF(key = "lvl", value,0)) AS `lvl`
FROM Player p
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId
GROUP By p.nickname
ORDER BY v1.value
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文