如何获得带有“加入”或“离开”值的最新行,并对它们进行排序?

时间:2018-02-11 23:51:31

标签: php mysql pdo

我有一张桌子可以跟踪游戏中玩家和每个服务器的加入和离开事件。我遇到的问题是,我如何知道谁离线以及谁在线?

这是我的表格结构,以及一些示例值:

CREATE TABLE `b_rbx_connections` (
  `id` int(11) NOT NULL,
  `server` varchar(48) NOT NULL,
  `place` int(11) NOT NULL,
  `player` int(11) NOT NULL,
  `type` enum('join','leave') NOT NULL,
  `followed` int(11) DEFAULT NULL COMMENT '0/null=none',
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `b_rbx_connections` (`id`, `server`, `place`, `player`, `type`, `followed`, `time`) VALUES
(1, '83889ac4-eaf9-45af-8b9d-fa1b14dba952', 1253620452, 50180001, 'join', NULL, '2018-02-10 06:04:30'),
(2, '83889ac4-eaf9-45af-8b9d-fa1b14dba952', 1253620452, 50180001, 'leave', NULL, '2018-02-10 06:32:27'),
(3, '9f1aabe0-e314-46f1-bb81-c45ea70fdae9', 1253620452, 50180001, 'join', NULL, '2018-02-11 22:54:53');

每次玩家加入行时都会插入服务器ID,地址ID,无论是加入还是离开,以及活动时间。

这是我到目前为止所尝试的,但它只适用于每个玩家只加入/离开一次:

$q = "SELECT DISTINCT player FROM `b_rbx_connections` WHERE place='$placeId' AND type='join' AND time <= '$timestamp' ORDER BY `time` DESC";
$j = $db->query($q);
$q = "SELECT DISTINCT player FROM `b_rbx_connections` WHERE place='$placeId' AND type='leave' AND time <= '$timestamp' ORDER BY `time` DESC";
$l = $db->query($q);

$this->players = $j->fetchAll(PDO::FETCH_COLUMN, 0);
$this->offline_players = $l->fetchAll(PDO::FETCH_COLUMN, 0);
$this->online_players = array_diff($this->players, $this->offline_players);

输出:

{
    "players": [
        "50180001"
    ],
    "offline_players": [
        "50180001"
    ],
    "online_players": [

    ]
}

但它应该是。

{
    "players": [
        "50180001"
    ],
    "offline_players": [

    ],
    "online_players": [
        "50180001"

    ]
}

注意:一个地方是游戏ID,服务器是该游戏中服务器的实例ID,而玩家是该玩家的id。

2 个答案:

答案 0 :(得分:1)

您应该在搜索中对播放器进行分组,以获得每个播放器的“最新”状态。然后使用该新数组来解析所需的结果。

SELECT  *
FROM (Select * FROM `b_rbx_connections` order by time desc) as results
GROUP BY player

查看http://sqlfiddle.com/#!9/fd03cb/3/0,我添加了更多播放器来测试查询。

答案 1 :(得分:0)

select p.player, (
    select c.type
    from b_rbx_connections c
    where c.player = p.player
      and c.place = 1253620452
    order by c.time desc
    limit 1
) as type
from b_rbx_players p

这将返回给定type的连接表中所有玩家和最后一行的place。如果播放器没有条目,type将为NULL(可以认为是离线)。

现在使用PHP循环将玩家分配到不同的阵列。