Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当前用户ID位于中心的排行榜榜首-SQL查询_Sql_Sql Server_Tsql - Fatal编程技术网

当前用户ID位于中心的排行榜榜首-SQL查询

当前用户ID位于中心的排行榜榜首-SQL查询,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有下表: +---------+------------+----------+-------+ | userId | campaignId | countryId| points| +---------+------------+----------+-------+ | 10 | 1 | 101 | 72 | | 3 | 1 | 101 | 30 | | 6 | 1

我有下表:

+---------+------------+----------+-------+
| userId  | campaignId | countryId| points| 
+---------+------------+----------+-------+
|      10 | 1          |      101 |    72 |
|       3 | 1          |      101 |    30 |
|       6 | 1          |      101 |    72 |
|       4 | 1          |      101 |    49 |
|       1 | 1          |      101 |    53 |
|       8 | 1          |      101 |    67 |
|       5 | 1          |      101 |     6 |
|       7 | 1          |      101 |    87 |
|       2 | 1          |      101 |    41 |
|      11 | 1          |      101 |    76 |
|       9 | 1          |      101 |    50 |
+---------+------------+----------+-------+
我已经创建了一个排行榜榜首列表,其查询如下:

    select 
       RANK() OVER(order by T.points desc) AS rowRank,
          T.UserID, T.points
        from table as T 
        where T.campaignId=@campaignId
OFFSET (@page-1)*@limit ROWS FETCH NEXT @limit ROWS ONLY
上面的查询从上到下返回一个常规的toplist

但是,下一个要求是创建一个排行榜toplist,返回当前用户Id排名+上面的2个排名用户+下面的2个排名用户,总共5个用户应与当前用户一起列在中心

因此,其他输入参数应为:

set @userId = 8 // current user where leader board should center around
set @maxTopLimit = 2 // include 2 users ranked above current user
set @maxBottomLimit = 2 // include 2 users ranked below current user
返回的排行榜应该是这样的,中间有userId8

        +---------+------------+----------+-------+---------|
        | userId  | campaignId | countryId| points| rowRank |
        +---------+------------+----------+-------+---------+
        |      11 | 1          |      101 |    76 |   3     |
        |      10 | 1          |      101 |    72 |   4     |
   #####|###### 8 | 1 #########|##### 101 |### 67 |## 5 ####|########
        |       9 | 1          |      101 |    50 |   6     |
        |       2 | 1          |      101 |    49 |   7     |
        +---------+------------+----------+-------+------+--+
如何编写这样的SQL查询

  • 在子查询或公共表表达式中移动排名结果。
    的cte\u排名为(…)
  • 选择目标用户。
    来自cte\u排名cr,其中cr.UserId=@UserId
  • 将目标行与定义间隔内的所有行联接。
    加入cr2.RowRank>=cr.RowRank-@before和cr2.RowRank上的cte_秩cr2
    
  • 在子查询或公共表表达式中移动排名结果。
    的cte\u排名为(…)
  • 选择目标用户。
    来自cte\u排名cr,其中cr.UserId=@UserId
  • 将目标行与定义间隔内的所有行联接。
    加入cr2.RowRank>=cr.RowRank-@before和cr2.RowRank上的cte_秩cr2
    
    create table CampaignPoints
    (
      UserId int,
      CampaignId int,
      CountryId int,
      Points int
    );
    
    insert into CampaignPoints (UserId, CampaignId, CountryId, Points) values
    (10, 1, 101, 72),
    ( 3, 1, 101, 30),
    ( 6, 1, 101, 72),
    ( 4, 1, 101, 49),
    ( 1, 1, 101, 53),
    ( 8, 1, 101, 67),
    ( 5, 1, 101,  6),
    ( 7, 1, 101, 87),
    ( 2, 1, 101, 41),
    (11, 1, 101, 76),
    ( 9, 1, 101, 50);
    
    declare @userId int = 8;
    declare @before int = 2;
    declare @after  int = 2;
    
    with cte_rank as
    (
      select cp.UserId,
             cp.CampaignId,
             cp.CountryId,
             cp.Points,
             rank() over(order by cp.Points desc) as RowRank
      from CampaignPoints cp
    )
    select cr2.*
    from cte_rank cr
    join cte_rank cr2
      on  cr2.RowRank >= cr.RowRank - @before
      and cr2.RowRank <= cr.RowRank + @after
    where cr.UserId = @userId
    order by cr2.RowRank;
    
    UserId  CampaignId  CountryId  Points  RowRank
    ------  ----------  ---------  ------  ------- 
    10      1           101        72      3
     6      1           101        72      3
     8      1           101        67      5
     1      1           101        53      6
     9      1           101        50      7