如何根据SQL中的双条件选择行上下10条记录 [英] How to select 10 records above and below row according to a double conditional in SQL

查看:70
本文介绍了如何根据SQL中的双条件选择行上下10条记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在为我的应用创建高分表时遇到问题.

I have run into a problem when creating a high score table for my app.

基本上,我希望能够查询服务器(解析)用户高分记录上下的 10 条记录并显示如下内容:

Basically, I want to be able to query a server (parse) for 10 records above and below the user's high score record and display something like this:

  • 45 个用户名 ...
  • 46 个用户名 ...
  • 47 个用户名 ...
  • 48 个用户名 ...
  • 49 个用户名 ...
  • 50 个用户名 ...
  • 51 用户名...
  • 52 个用户名 ...
  • 53 个用户名 ...
  • 54 个用户名 ...
  • 55 个用户的高分
  • 55 个用户名 ...
  • 56 个用户名 ...
  • 57 个用户名 ...
  • 58 个用户名 ...
  • 59 个用户名 ...
  • 60 个用户名 ...
  • 61 用户名...
  • 62 用户名...
  • 63 用户名...
  • 64 用户名...

从技术上讲,我没有使用 SQL,我使用的是 Parse IOS API.但逻辑是一样的,所以如果我能弄清楚如何用 SQL 来做,我可以使用 Parse API 来做.

Technically, I am not using SQL, I am using the Parse IOS API. But the logic is the same so if I can figure out how to do it in SQL, I can do it using the Parse API.

一个看似简单的解决方案是找到用户的高分并对 10 条得分高于用户的记录进行查询,然后将其与对低于用户的 10 条记录的查询结合起来.

An seemingly simple solution would be to find the user's high score and run a query for 10 records where the score is greater than the user's and join that with a query for 10 records below the user's.

这不起作用,因为当两个用户的高分相同时(这在这个应用程序中经常发生)我想显示首先获得高分的用户高于其他用户.例如,如果比尔在 11 月 1 日得了 41 分,而鲍勃在 11 月 2 日得了 41 分,那么比尔在排名表上就会高于鲍勃.

This doesn't work because when two user's have the same high score (this will happen often in this app) I want to show the user who obtained the high score first as being above the others. For instance, if Bill scored 41 on Nov 1st and Bob scored 41 on Nov 2nd, Bill would be above Bob on the ranking table.

我用来排序的两列是:

  • highScore:数字
  • createdAt:日期

如果我只是找到前 50 名或类似的分数,那么这个双条件很容易实现,但我不知道如何将查询集中在一条记录上.

This double conditional is easy to implement if I am just finding the top 50 scores or something like that but I can't figure out how to center the query around a single record.

编辑(我的临时解决方案)我找到了一个有效但并不完美的临时解决方案:

EDIT (my temporary solution) I found a temporary solution that works but is not perfect:

将查询拆分为 4 个查询:

Split the query into 4 queries:

  • q1:highScore > userScore;降序->高分;升序->createdAt;限制 10
  • q2:highScore == userScore;createdAt <= userDate;降序->高分;升序->createdAt;限制 10
  • q3:highScore == userScore;createdAt > 用户日期;降序->高分;升序->createdAt;限制 10
  • q4:highScore <用户评分;降序->高分;升序->createdAt;限制 10

然后,如果 q2 返回的记录少于 10 条,则使用 q1 填充剩余的记录.如果 q3 返回的记录少于 10 条,则用 q4 填充.最多只返回 40 条记录以显示 20 条记录,因此这不会浪费太多查询.

Then, if q2 returns less than 10 records, fill the remaining ones using q1. If q3 returns less than 10 records, fill it with q4. At most, this returns only 40 records to display 20, so this will work with not much wasted querying.

推荐答案

在 SQL 中,您可以使用 union all 来做到这一点,首先得到分数较高或相等的 11 行,然后分数较低的 10 行:

In SQL, you can do this with a union all, first to get the 11 rows with higher or equal scores and then the 10 rows with lower scores:

(select s.*
 from scores s
 where s.score >= (select max(score) from scores where user = $USER)
 order by s.score asc
 limit 11
)
union all
(select s.*
 from scores s
 where s.score <= (select max(score) from scores where user = $USER) and users <> $USER
 order by s.score desc
 limit 10
)

这篇关于如何根据SQL中的双条件选择行上下10条记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆