Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:GroupPlayerUID,显示总杀死数和活角色的最新坐标_Mysql - Fatal编程技术网

MySQL:GroupPlayerUID,显示总杀死数和活角色的最新坐标

MySQL:GroupPlayerUID,显示总杀死数和活角色的最新坐标,mysql,Mysql,我已经挣扎了一段时间,还没有找到解决办法 我有一个MySQL数据库表,其中包含游戏角色数据,有以下列: CharacterID:一旦玩家死亡,他将获得新角色,这将添加一个新条目 PlayerUID:对每个玩家都是唯一的。我们需要按此分组 KillsZ:显示每个角色有多少次杀戮 世界空间:角色的位置 活着:角色是活着还是死了 所以我需要一个SQL查询,返回玩家的总击杀数和他们当前角色的坐标。我怎么能这样做 我认为应该是这样的: SELECT CharacterID, PlayerUID, su

我已经挣扎了一段时间,还没有找到解决办法

我有一个MySQL数据库表,其中包含游戏角色数据,有以下列:

  • CharacterID:一旦玩家死亡,他将获得新角色,这将添加一个新条目
  • PlayerUID:对每个玩家都是唯一的。我们需要按此分组
  • KillsZ:显示每个角色有多少次杀戮
  • 世界空间:角色的位置
  • 活着:角色是活着还是死了
所以我需要一个SQL查询,返回玩家的总击杀数和他们当前角色的坐标。我怎么能这样做

我认为应该是这样的:

SELECT CharacterID, PlayerUID, sum(KillsZ), Worldspace, alive
FROM character_data
WHERE Worldspace IN (SELECT Worldspace FROM character_data WHERE alive = 1)
GROUP BY PlayerUID
ORDER BY sum(KillsZ) DESC;
输出:(顶部11行)

以下是不带以下内容的查询:

SELECT CharacterID, PlayerUID, sum(KillsZ), Worldspace, alive
FROM character_data
GROUP BY PlayerUID
ORDER BY sum(KillsZ) DESC;
哪个输出:(11排最上面)


您可以看到总杀死数是不同的。

让我们使用SQLite重新创建您的表:

sqlite> create table characters(playerid integer, kills integer, x integer, y integer, alive integer);
sqlite> insert into characters values(1, 10, 20, 40, 0);
sqlite> insert into characters values(1, 20, 30, 40, 0);
sqlite> insert into characters values(2, 99, 33, 66, 1);
sqlite> insert into characters values(1, 11, 22, 33, 1);
注意:SQLite表有一个implict
rowid
列,我们将使用它作为
characterid
字段

您可以很容易地获得当前“活动”字符的坐标:

sqlite> SELECT playerid, x, y FROM characters WHERE alive = 1; 
2|33|66
1|22|33
也可以很容易地得到总的死亡人数:

sqlite> SELECT playerid, SUM(kills) FROM characters GROUP BY playerid;
1|41
2|99
鉴于上述情况,这应该是将这两组结果结合在一起的简单情况:

sqlite> SELECT * FROM (SELECT playerid, x, y FROM characters WHERE alive = 1) AS A LEFT JOIN (SELECT playerid, SUM(kills) FROM characters GROUP BY playerid) AS B ON A.playerid = B.playerid;
2|33|66|2|99
1|22|33|1|41

当按结果集分组时,标准SQL要求对不在
GROUP BY
子句中的任何列使用聚合函数。这是因为每个组对应多行,非分组列中的值不同(或可能不同)。您的查询引用这些值中的哪一个?其他DBMS不会处理像您问题中那样的不明确查询,但前提是您只会在非分组列中的所有可能值在一个组中都是常量的情况下进行处理

听起来您想要的是与玩家相关的所有角色的总杀戮数,这很容易,只要将每组的
KillsZ
列相加即可:

SELECT
  PlayerUID,
  SUM(KillsZ) AS TotalKills
FROM character_data
GROUP BY PlayerUID;
要添加当前活动字符的坐标,可以使用
大小写
表达式将对应于死字符的每行坐标置零,然后使用聚合函数
MAX
获取剩余的单个值:

SELECT
  PlayerUID,
  SUM(KillsZ) AS Total_Kills,
  MAX(CASE WHEN alive = 1 THEN Worldspace END) AS Current_Coordinates
FROM character_data
GROUP BY PlayerUID;
这是一个简单的查询,只对数据进行一次传递,并且可以通过适当的覆盖索引(如果性能需要)来满足。相比之下,建议外部将表连接到自身的解决方案相当复杂,但如果重要的话,可以通过较小的索引来满足。这两种解决方案之间的一个重要区别是,我的解决方案将向您展示只有死亡角色的玩家,而目前编写的另一个解决方案则不会

这取决于一个重要的假设,即任何组中只有一行在任何给定时间具有
alive=1
。您可能需要考虑在数据库中强制执行此约束。只要一个玩家在数据库中最多只能有一个活着的角色,你就可以从
MAX
MIN
中得到相同的结果,并且可以使用任何一个。如果您的坐标值是数值,您甚至可以使用
SUM
,尽管我认为这会有点误导(如果您的坐标存储为CHAR类型,则不起作用)


在MySQL中,您可以用IF(alive=1,Worldspace,NULL)替换这个简单的
CASE
表达式,但由于它的可移植性较差,而且不太详细,因此我建议您坚持使用SQL标准中的
CASE

它在某种程度上会弄乱总体杀戮。一些字符的总数不会达到应有的水平。你能发布一些示例数据吗?您应该使用
SUM(killsz)
来代替吗?非常感谢!看来在你的帮助下,我的工作正是我想要的。
SELECT
  PlayerUID,
  SUM(KillsZ) AS TotalKills
FROM character_data
GROUP BY PlayerUID;
SELECT
  PlayerUID,
  SUM(KillsZ) AS Total_Kills,
  MAX(CASE WHEN alive = 1 THEN Worldspace END) AS Current_Coordinates
FROM character_data
GROUP BY PlayerUID;