我是SQL查询的新手,我需要获得一些活跃玩家的最后位置,这意味着他们的Play值等于1.我必须在表Events
之间建立联接我有玩家活动的地方:
使用表格Positions
,其中所有玩家每隔2-3秒使用列位置:
以获取活跃玩家的当前纬度和经度。
我当前的查询:
select
e.PlayerId, e.Active,
p.Location.Lat, p.Location.Long,
max_date = max(e.Timestamp),
max_date2 = max(p.Timestamp)
from
Events e
inner join
Positions p on e.PlayerId = p.PlayerId
where
e.Active= 1
group by
e.PlayerId, e.Active, p.Location.Lat, p.Location.Long
但不是返回2行我得到更多。我想这是因为group by子句中的b.Location.Lat, b.Location.Long
字段,因为简单查询:
select
e.PlayerId, e.Active,
max_date = max(e.Timestamp),
max_date2 = max (p.Timestamp)
from
Events e
inner join
Positions p on e.PlayerId = p.PlayerId
where
e.Active = 1
group by
e.PlayerId, e.Active
返回正确的2行,但我还需要获取Lat-Long列。
更新 我在查询中发现了一个问题。当我再次针对不同的值运行它时,我已经看到它返回所有玩家的位置,如果他们甚至只有一次活动,之后他们就变得不活跃。但是,如果一个用户的Active的最后一个值(根据最大时间戳)为0,则查询应从响应中删除播放器位置。
有没有什么办法可以添加这些列而不会获得比所需更多的行?
答案 0 :(得分:1)
您可以将当前查询包装在外部查询中,然后再次加入到您的位置表。像这样的东西;
SELECT
base.PlayerId
,base.Active
,base.max_date
,base.max_date2
,p.Location.lat
,p.Location.long
FROM
(
SELECT a.PlayerId ,
a.Active,
max_date = max( a.Timestamp ),
max_date2 = max (b.Timestamp)
FROM Events a
INNER JOIN Positions b
ON a.PlayerId =b.PlayerId
WHERE a.Active= 1
GROUP BY a.PlayerId , a.Active
) base
JOIN Positions p
ON base.PlayerId = p.PlayerId
AND base.max_date2 = p.Timestamp
您的其他查询无效的原因是您要为每个lat& amp;长点。这样做会为您提供您之后的唯一列表,然后再次加入Positions以获取lat长信息。
编辑:根据评论,如果要排除最新Active值设置为零的任何人,请将其添加到代码的末尾;
JOIN
(
SELECT
e.PlayerID
,MAX(e.Timestamp) Timestamp
FROM Events e
GROUP BY e.PlayerID
) latest
ON base.PlayerID = latest.PlayerID
JOIN Events e2
ON latest.PlayerID = e2.PlayerID
AND latest.Timestamp = e2.Timestamp
WHERE e2.Active <> 0