4

我对以下功能有疑问:

function get_organization_score($org_id)
{
  $sql1 = "SET @rownum := 0";
  $sql2 = "SELECT rank, xp_total FROM (
           SELECT @rownum := @rownum + 1 AS rank, g_org.id AS org_id,
           (Sum(g_npc.xp) + (Sum(g_npc.level)*128)) AS xp_total FROM g_org
           LEFT JOIN g_npc ON g_org.id = g_npc.g_org_id GROUP BY g_org.id
           ORDER BY xp_total DESC
                          ) as result WHERE org_id='".$org_id."'";
  mysql_query($sql1);
  $result = mysql_query($sql2);
  $rows = '';
  $data = array();
  if (!empty($result))
      $rows = mysql_num_rows($result);
  else
      $rows = '';
  if (!empty($rows)){
      while ($rows = mysql_fetch_assoc($result)){
          $data[] = $rows;
      }
  }
  if (empty($data[0]['rank']))
      return 1;
  return $data[0]['rank'];
}

此代码用于在记分牌中显示组织排名。因此,例如,当我提供组织 ID 时,我会在记分牌中获得其排名编号。

目前的问题是我没有得到等级编号,而是我将函数称为组织 ID 的 ID 本身。

示例: get_organization_score(1) 然后我得到排名编号为 1 或者当我调用 get_organization_score(34) 然后我得到排名编号为 34

但我希望它在记分牌中的位置按左连接来自其他表的 XP 数量排序。

任何人都可以帮忙吗?如果有任何问题请询问...

编辑:添加表模式和示例数据:

CREATE TABLE IF NOT EXISTS `g_org` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `org_name` varchar(255) NOT NULL,
  `founded` datetime NOT NULL,
  `g_userid` int(255) NOT NULL,
  `g_username` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `g_userid` (`g_userid`),
  KEY `g_username` (`g_username`(191)),
  KEY `g_username_2` (`g_username`),
  KEY `org_name` (`org_name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=47 ;

INSERT INTO `g_org` (`id`, `org_name`, `founded`, `g_userid`, `g_username`) VALUES
(1, 'test_org_1', '2012-07-04 02:30:56', 1, 'DDD'),
(2, 'test_org_2', '2012-07-04 02:34:57', 2, '777');

--
-- Table structure for table `g_npc`
--

CREATE TABLE IF NOT EXISTS `g_npc` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `g_userid` int(255) NOT NULL,
  `g_username` varchar(255) NOT NULL,
  `g_org_id` int(255) NOT NULL,
  `g_org_name` varchar(255) NOT NULL,
  `g_npc_name` varchar(255) NOT NULL,
  `level` int(255) NOT NULL,
  `xp` int(255) NOT NULL,
  `last_update` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `g_userid` (`g_userid`),
  KEY `g_username` (`g_username`),
  KEY `g_org_id` (`g_org_id`),
  KEY `g_org_name` (`g_org_name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=181 ;


INSERT INTO `g_npc` (`id`, `g_userid`, `g_username`, `g_org_id`, `g_org_name`, `g_npc_name`, `level`, `xp`, `last_update`) VALUES
(1, 1, 'DDD', 1, 'test_org_1', 'Kinuzehute Doqasi', 4, 155, '2012-11-13 14:30:54'),
(2, 1, 'DDD', 1, 'test_org_1', 'Zabava Qigatagise', 2, 107, '2012-10-30 17:38:12'),
(3, 2, '777', 2, 'test_org_2', 'Roci Vuzoducu', 6, 135, '2012-11-13 23:17:40'),
(4, 2, '777', 2, 'test_org_2', 'Gexoye Zeze', 4, 638, '2012-11-06 02:02:27'),
(5, 2, '777', 2, 'test_org_2', 'Sibalabu Gozi', 9, 285, '2012-11-06 02:02);

当我调用函数 get_organization_score(2); 那么组织ID将为2,我想查询ID为2的表'g_org'并左连接表'g_npc'以获取'g_npc'表中'g_org_id'值为2的所有条目并求和来自“g_npc”表字段“xp”的所有结果,然后按字段“xp”DESC 排序所有这些结果。

然后,带有@rownum 的剩余 PHP 代码将给该组织在其他组织中的排名。

因此,组织 ID 2 的以下函数将导致排名为 1,因为它在“xp”字段中有更多 XP,当我使用组织 ID 1 调用相同的函数时,排名数字将为 2,因为它的数字较小在“XP”字段中。

基本上我不想产生组织列表,而只是排名数字。没有其他的。

结尾应该有 WHERE org_id='".$org_id."' 因为它只需要获取 1 个条目的排名号。

4

1 回答 1

1

我唯一能想到的是这个非常慢的代码:

select rank from (
  select s1.id, @row := @row + 1 rank from (
    select
      o.id,
      sum(coalesce(n.xp, 0) + coalesce(n.level, 0) * 128) totalXP
    from g_org o
    left join g_npc n on (o.id = n.g_org_id)
    group by o.id
    order by totalXP desc
  ) s1, (select @row := 0) init
) s2
where id = 1

请注意,无需运行SET查询并记住替换id = 1为您在 PHP 中使用的任何内容。

于 2012-11-18T05:44:26.817 回答