我的用户数据库中有tbl_items我希望对具有特定ID的特定项目的用户排名进行排序(514)。我使用这组数据在我的开发环境中测试数据:
mysql> select * from tbl_items where classid=514;
+---------+---------+----------+
| ownerId | classId | quantity |
+---------+---------+----------+
| 1 | 514 | 3 |
| 2 | 514 | 5 |
| 3 | 514 | 11 |
| 4 | 514 | 46 |
| 5 | 514 | 57 |
| 6 | 514 | 6 |
| 7 | 514 | 3 |
| 8 | 514 | 27 |
| 10 | 514 | 2 |
| 11 | 514 | 73 |
| 12 | 514 | 18 |
| 13 | 514 | 31 |
+---------+---------+----------+
12 rows in set (0.00 sec)
到目前为止这么好:)我写了以下查询:
set @row=0;
select a.*, @row:=@row+1 as rank
from (select a.ownerid,a.quantity from tbl_items a
where a.classid=514) a order by quantity desc;
+---------+----------+------+
| ownerid | quantity | rank |
+---------+----------+------+
| 11 | 73 | 1 |
| 5 | 57 | 2 |
| 4 | 46 | 3 |
| 13 | 31 | 4 |
| 8 | 27 | 5 |
| 12 | 18 | 6 |
| 3 | 11 | 7 |
| 6 | 6 | 8 |
| 2 | 5 | 9 |
| 7 | 3 | 10 |
| 1 | 3 | 11 |
| 10 | 2 | 12 |
+---------+----------+------+
12 rows in set (0.00 sec)
正确排名用户。但是在包含大量记录的表中,我需要执行以下操作:
1)能够获得列表的一小部分,即用户排名实际所在的位置,这将使我获得周围的记录,保留整体排名: 我尝试通过将用户变量设置为当前用户的排名并使用偏移和限制来做这些事情,但不能保持整体排名。
这应该让我得到以下内容(例如ownerId = 2和环境限制5:
+---------+----------+------+
| ownerid | quantity | rank |
+---------+----------+------+
| 3 | 11 | 7 |
| 6 | 6 | 8 |
| 2 | 5 | 9 | --> ownerId=2
| 7 | 3 | 10 |
| 1 | 3 | 11 |
+---------+----------+------+
5 rows in set (0.00 sec)
2)我还需要另一个查询(最好是单个查询),它可以获得前3个地方+具有特定ID的特定用户的排名,最好只有一个查询,无论他是&# 39;跻身前三名之列。我也无法做到这一点
它看起来如下(例如ownerId = 2):
+---------+----------+------+
| ownerid | quantity | rank |
+---------+----------+------+
| 11 | 73 | 1 |
| 5 | 57 | 2 |
| 4 | 46 | 3 |
| 2 | 5 | 9 | --> ownerId=2
+---------+----------+------+
4 rows in set (0.00 sec)
此外,我对有数百万条记录的表格上的查询性能表示担忧...... 希望有人帮忙:)。
答案 0 :(得分:1)
1)给定身份的5个条目。
set @row=0;
set @rk2=-1;
set @id=2;
select b.* from (
select a.*, @row:=@row+1 as rank, if(a.ownerid=@id, @rk2:=@row, -1) as rank2
from (
select a.ownerid,a.quantity
from tbl_items a
where a.classid=514) a
order by quantity desc) b
where b.rank > @rk2 - 3
limit 5;
虽然您将获得额外的列rank2
:您可能希望通过明确的列列表而不是b.*
来过滤它。也许它可能是having
条款而不是额外的嵌套。
2)3个排名靠前的条目+ 1个特定的id
select b.* from (
select a.*, @row:=@row+1 as rank
from (
select a.ownerid,a.quantity
from tbl_items a
where a.classid=514) a
order by quantity desc) b
where b.rank < 4 or b.ownerid=@id