MySQL: select 5 rows before and after specific row

后端 未结 5 514
陌清茗
陌清茗 2020-12-20 23:26

I have table called \"users\" and need to select 2 rows before and after specific row, sorted by users.score ASC

users table (structure):

id     name         


        
相关标签:
5条回答
  • 2020-12-21 00:09
    (SELECT x.* FROM users x JOIN users y ON y.score <= x. score WHERE y.id = 5 ORDER BY score LIMIT 3)
    UNION
    (SELECT x.* FROM users x JOIN users y ON y.score >= x. score WHERE y.id = 5 ORDER BY score DESc LIMIT 3)
    [ORDER BY score]    ;
    

    http://www.sqlfiddle.com/#!9/45c22/42

    0 讨论(0)
  • 2020-12-21 00:13

    Selecting arbitrarily ordered rows before and after a specific id

    SET @j = 0;
    SET @i = 0;
    SELECT *
    FROM ( 
        SELECT id, col1, col2, ..., @j:=@j+1 AS pos
        FROM `table`
        WHERE  col1=... ORDER BY col1 DESC, col2 ASC
    ) AS zz
    WHERE (    
        SELECT position
        FROM ( 
            SELECT id AS id2, @i:=@i+1 AS position
            FROM `table`
            WHERE  col1=... ORDER BY col1 DESC, col2 ASC
        ) AS zz
        WHERE id2=$currId
    )
    IN (pos-5,pos-4,pos-3,pos-2,pos-1,pos,pos+1,pos+2,pos+3,pos+4,pos+5)
    
    0 讨论(0)
  • 2020-12-21 00:18

    Using union all and subqueries to limit the records should do it:

    select * from  users where id = 5
    union all (
      select * from users 
      where score <  (select score from users where id = 5) 
      order by score desc limit 2
    ) 
    union all (
      select * from users 
      where score > (select score from users where id = 5) 
      order by score asc limit 2
    ) 
    order by score
    

    Sample SQL Fiddle

    Edit: I think a better method is to number the rows according to score and then select the rows with number -2 and +2 from the rows of id 5:

    select id, name, score 
    from (select 
          t.*, @rownum1 := @rownum1 + 1 as rank
          from users t, (select @rownum1 := 0) r
          order by score
         ) a,
         (select rank from (
            select t.*, 
            @rownum := @rownum + 1 as rank
            from users t, (select @rownum := 0) r
            order by score
         ) t
          where id = 5
       ) b
    where b.rank between a.rank -2 and a.rank+2
    order by score;    
    

    Sample SQL Fiddle

    0 讨论(0)
  • 2020-12-21 00:23

    I just write the query, based on "jpw" solution (many thanks to him)

    select * from  users where id = 5
    union all (
      select * from users 
      where id in (select id from users where score < (select score from users u where u.id = 5) order by score ASC)
      order by score desc limit 2
    ) 
    union all (
      select * from users 
      where id in (select id from users where score > (select score from users u where u.id = 5) order by score ASC)
      order by score ASC limit 2
    ) 
    order by score
    
    0 讨论(0)
  • 2020-12-21 00:29

    Perhaps using union all

    (
     select * from users where id < 5 order by score limit 2
    )
    union all
    (
      select * from users where id > 5 order by score limit 2
    )
    
    0 讨论(0)
提交回复
热议问题