【发布时间】:2017-03-30 08:08:05
【问题描述】:
我会向 SO 寻求帮助,因为我找不到类似的情况、问题/发布我的问题
假设我有数百万条记录,列是
user_id - 假设其记录从 1 到 1,000,000
名称 - 假设它在字母表中也记录了最多 20 个字符
分数 - 0 到 100 假设它也被记录了
日期 - 记录日期(时间戳)
user_id | name | score | date |
------------------------------------------------
23131 | name1 | 15 | 2017-01-04 02:01:25
26824 | name2 | 63 | 2017-01-04 02:41:33
19684 | name3 | 28 | 2017-01-04 02:56:15
74937 | name4 | 01 | 2017-01-04 04:07:55
27486 | name5 | 75 | 2017-01-04 13:07:45
86476 | name6 | 56 | 2017-01-04 14:21:47
36479 | name7 | 19 | 2017-01-04 17:11:15
86752 | name8 | 38 | 2017-01-04 18:22:23
11267 | name9 | 100 | 2017-01-04 20:34:42
88763 | name10 | 89 | 2017-01-04 22:45:43
- 如果我知道我的 user_id 是什么,我想知道自己的排名
- 我还想得到其他10条用户记录在我的排名上下,假设我的排名是100,我也想选择排名在90到99(高于我的排名)和101到110(低于我的排名)的用户).
如果不同的用户按记录日期的得分顺序排名相同,则较早的记录具有较高的排名。
有可能吗?
假设所有记录都是唯一的并且没有设置索引。
我知道如何排序
SELECT * FROM record order by score
但这会让我选择所有记录,在不选择每条记录的情况下选择特定数据的实用方法是什么?
这是我想要实现的目标
user_id | name | score | date | rank |
------------------------------------------------------------------
12341 | namep | 90 | 2017-01-01 04:02:36 | 90 |
45341 | nameo | 88 | 2017-01-02 00:05:45 | 91 |
24341 | namex | 88 | 2017-01-03 00:11:15 | 92 |
26867 | namec | 83 | 2017-01-03 01:41:23 | 93 |
19156 | nameb | 81 | 2017-01-03 02:36:45 | 94 |
74973 | namem | 79 | 2017-01-03 04:07:55 | 95 |
23134 | namek | 78 | 2017-01-04 02:01:25 | 96 |
21424 | namet | 77 | 2017-01-04 02:41:33 | 97 |
19534 | nameg | 77 | 2017-01-04 02:56:15 | 98 |
74912 | namez | 75 | 2017-01-04 04:07:55 | 99 |
my_uid | my_name | 75 | 2017-01-04 13:07:45 | 100 |
86766 | namen | 75 | 2017-01-04 14:21:47 | 101 |
67976 | namey | 74 | 2017-01-04 16:22:23 | 102 |
34676 | nameu | 74 | 2017-01-04 17:33:32 | 103 |
86236 | namei | 73 | 2017-01-04 18:11:09 | 104 |
98636 | nameo | 73 | 2017-01-04 19:21:47 | 105 |
14326 | namep | 73 | 2017-01-04 20:33:22 | 106 |
45333 | namet | 72 | 2017-01-04 20:44:12 | 107 |
33323 | namer | 72 | 2017-01-04 21:34:26 | 108 |
11322 | namee | 71 | 2017-01-04 22:51:54 | 109 |
86633 | namew | 70 | 2017-01-04 22:55:33 | 110 |
好的,这就是我现在得到的,很抱歉我没有提到任何关于不使用 union 或 union all 的内容,我不能在我的项目中使用它。
但无论如何这是我的查询 我使用了“multi_query()”函数
$sql = "SELECT score, date FROM table_name WHERE user_id=your_user_id;" //assume you already know your user_id
$sql .= "SELECT name, score, date FROM table_name WHERE score >= your_score ORDER BY score, date LIMIT 10;"; //to get 10 rows that have greater or same score of your score order by date, earlier date is higher rank if score is the same with other user.
$sql .= "SELECT name, score, date table_name WHERE score <= your_score DESC, date ASC LIMIT 10"; //select score less than or equal to my score order by score and date
我得到这样的东西
my_uid | my_name | 75 | 2017-01-04 13:07:45 | 100 |
12341 | namep | 90 | 2017-01-01 04:02:36 | 90 |
45341 | nameo | 88 | 2017-01-02 00:05:45 | 91 |
24341 | namex | 88 | 2017-01-03 00:11:15 | 92 |
26867 | namec | 83 | 2017-01-03 01:41:23 | 93 |
19156 | nameb | 81 | 2017-01-03 02:36:45 | 94 |
74973 | namem | 79 | 2017-01-03 04:07:55 | 95 |
23134 | namek | 78 | 2017-01-04 02:01:25 | 96 |
21424 | namet | 77 | 2017-01-04 02:41:33 | 97 |
19534 | nameg | 77 | 2017-01-04 02:56:15 | 98 |
74912 | namez | 75 | 2017-01-04 04:07:55 | 99 |
74912 | namez | 75 | 2017-01-04 04:07:55 | 99 |
my_uid | my_name | 75 | 2017-01-04 13:07:45 | 100 |
86766 | namen | 75 | 2017-01-04 14:21:47 | 101 |
67976 | namey | 74 | 2017-01-04 16:22:23 | 102 |
34676 | nameu | 74 | 2017-01-04 17:33:32 | 103 |
86236 | namei | 73 | 2017-01-04 18:11:09 | 104 |
98636 | nameo | 73 | 2017-01-04 19:21:47 | 105 |
14326 | namep | 73 | 2017-01-04 20:33:22 | 106 |
45333 | namet | 72 | 2017-01-04 20:44:12 | 107 |
33323 | namer | 72 | 2017-01-04 21:34:26 | 108 |
我的问题是当使用多个查询时,由于我有 3 个查询,它仍然与执行 3 个不同的查询相同,我如何将它们组合为一个?不使用 union 或 union all?
在第三个查询中,如何从我的数据中设置起点?
【问题讨论】:
-
@Takarii 谢谢你的回复 我会看看这个帖子!
-
查看 MariaDB 中可用的“窗口函数”。
-
@RickJames 感谢您的回复!我忘了提到我必须使用 MySQL,但我会看看“Windowing Functions”。
-
@Takarii 在我的项目中我不能使用 union 或 union all,这可能吗?