我有一个表格,其中包含玩家在任何一天所采取步骤的信息,我想从数据库中获得3个最高总数,当高总数的前一天为该玩家添加了一个值时。由于有些玩家不是每天都在记录,而是将多天的时间归结为一次更新。
数据结构:
|---------------------------------------------------------------|
| id | player_id | steps | date | submitted |
|----|-----------|-------|------------|-------------------------|
| 1 | 16 | 5718 | 2012-09-06 | 2012-09-10 08:31:35.000 |
| 2 | 16 | 9837 | 2012-09-07 | 2012-09-10 08:31:17.000 |
| 3 | 16 | 10432 | 2012-09-09 | 2012-09-10 08:30:54.000 |
| 4 | 30 | 3973 | 2012-09-07 | 2012-09-10 09:34:42.000 |
| 5 | 30 | 7104 | 2012-09-08 | 2012-09-10 09:35:05.000 |
| 6 | 30 | 10916 | 2012-09-09 | 2012-09-10 09:35:29.000 |
| 7 | 9 | 6437 | 2012-09-07 | 2012-09-10 09:39:15.000 |
| 8 | 9 | 9032 | 2012-09-08 | 2012-09-10 09:40:02.000 |
|---------------------------------------------------------------|
所以我要返回的是行:
|---------------------------------------------------------------|
| 6 | 30 | 10916 | 2012-09-09 | 2012-09-10 09:35:29.000 |
| 2 | 16 | 9837 | 2012-09-07 | 2012-09-10 08:31:17.000 |
| 8 | 9 | 9032 | 2012-09-08 | 2012-09-10 09:40:02.000 |
|---------------------------------------------------------------|
我的查询目前是:
SELECT TOP 3 p.name,
player_id,
steps,
date
FROM steppers_step_log
JOIN steppers_players P
ON player_id = P.id
ORDER BY steps DESC
其中没有考虑到前三个步骤中的日期条目,以我当前形式的查询将返回10432,10916和9837作为顶部步骤。
我无法弄清楚如何执行WHERE命令以确保前一天有该player_id的条目,并希望获得任何帮助以使其正常工作。
答案 0 :(得分:3)
这样的东西?
SELECT TOP 3 p.name,
player_id,
steps,
date
FROM steppers_step_log
JOIN steppers_players P
ON player_id = P.id
WHERE EXISTS
(
SELECT 1 FROM steppers_step_log ssp
WHERE ssp.player_id = P.id
AND date = DATEADD(day, -1, steppers_step_log.date)
)
ORDER BY steps DESC
答案 1 :(得分:1)
您只需使用WHERE
条件添加EXISTS
子句......
SELECT TOP 3
p.name,
player_id,
steps,
date
FROM
steppers_step_log AS log
INNER JOIN
steppers_players AS players
ON log.player_id = players.id
WHERE
EXISTS (
SELECT *
FROM steppers_step_log
WHERE player_id = players.id
AND date = log.date - 1
)
ORDER BY
log.steps DESC
这个可以但是,不止一次返回同一个玩家;如果他们在前3名中有多个参赛作品。这就是你想要的吗?
答案 2 :(得分:1)
有几种方法可以解决这个问题。其他人可能会使用join / exists类型查询来执行解决方案。我喜欢使用排名函数来获取适当行的替代方法。
您正在寻找的是上传序列,然后您不需要第一个。您可以通过枚举播放器的行来定义序列。然后,对于每个序列,日期和序列之间的差异是常数。然后,额外的排名可以得到你想要的。
定义序列:
select stl.*,
row_number() over (partition by player_id, groupid order by date) as seqnum
from (select stl.*,
datediff(day, date,
row_number() over (partition by player_id order by date) as groupid
from steppers_step_log stl
) stl
现在,您可以使用以下方式获取“符合条件”的行:
where seqnum > 1
要获得每个玩家的三个最高值,您可以这样做:
with stl as (<above query>)
select *
from (select stl.*,
row_number() over (partition by player_id order by steps desc) as scorenum
from stl
where seqnum > 1
) stl
where scorenum <= 3