为每个id选择10行

时间:2018-06-08 12:40:34

标签: mysql

如何为每个id_recipient获取10行?

SELECT id FROM msg WHERE id_recipient IN (1,2,3,4,5)

因此请求应返回50行(每个id_recipient 10行)

4 个答案:

答案 0 :(得分:3)

您可以使用ROW_NUMBER(MySQL 8.0 +):

SELECT sub.id
FROM (SELECT id,
         ROW_NUMBER() OVER(PARTITION BY id_recipient ORDER BY some_col) AS rn
     FROM msg 
     WHERE id_recipient IN (1,2,3,4,5)) AS sub
WHERE rn <= 10;

答案 1 :(得分:0)

这是一种方法 - 虽然它没有特别好地扩展......

SELECT * FROM my_table;
+---------+-----+
| entryID | ID  |
+---------+-----+
|     331 | 136 |
|     332 | 136 |
|     333 | 136 |
|     334 | 136 |
|     335 | 136 |
|     336 | 136 |
|     337 | 137 |
|     338 | 137 |
|     339 | 137 |
|     340 | 137 |
+---------+-----+

SELECT x.*
  FROM my_table x 
  JOIN my_table y 
    ON y.id = x.id 
   AND y.entryid <= x.entryid 
 GROUP  
    BY x.entryid 
HAVING COUNT(*) <=3;
+---------+-----+
| entryID | ID  |
+---------+-----+
|     331 | 136 |
|     332 | 136 |
|     333 | 136 |
|     337 | 137 |
|     338 | 137 |
|     339 | 137 |
+---------+-----+

......这里有一个可以很好地扩展的方法,但也许MySQL8.0的现代方法更好。

SELECT a.entryid
     , a.id
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev = id THEN @i:=@i+1 ELSE @i:=1 END i
            , @prev := id
         FROM my_table x
            , (SELECT @prev := null, @i:=0) vars
        ORDER
           BY entryid
     ) a
 WHERE i <=3
 ORDER
    BY entryid;

答案 2 :(得分:0)

如果您没有机会参加MYSQL 8.0:

SELECT sub.id
FROM (SELECT id,
         @cnt := IF(@last_id = id , @cnt +1, 1) AS dummy_cnt,
         @last_id := id AS dummy_id
     FROM msg 
     CROSS JOIN (SELECT @cnt := 0, @last_id:= 0) var
     WHERE id_recipient IN (1,2,3,4,5)
     ORDER BY id) AS sub
WHERE dummy_cnt <= 10
ORDER BY sub.id;

答案 3 :(得分:0)

对于MySQL 5.5+

请注意,查询未经过测试,因此可能包含错误。

SELECT 
 *
FROM (
  SELECT 
       msg.*
     , (CASE WHEN @id = msg.id THEN @rank := @rank + 1 ELSE @rank := 1 END) AS rank
     , (@id := msg.id) AS init_id
  FROM 
   msg 
  WHERE
   msg.id_recipient IN(1,2,3,4,5)
  CROSS JOIN ( SELECT @id := 0, @rank := 0) AS init_user_variables
  ORDER BY
   msg.some_column ASC
) AS msg_ranked
WHERE
 msg_ranked.rank <= 10

对于所有MySQL版本和大多数数据库,但由于与共同相关的子查询非常慢。

SELECT 
 *
 , (
     SELECT
      COUNT(*) AS rank
     FROM 
      msg msgInner
     WHERE           
          msgInner.id_recipient = msgOuter.id_recipient 
        AND
          msgInner.id > msgOuter.id
     ORDER BY
      msgInner.some_column ASC

   ) AS rank
FROM 
 msg msgOuter
WHERE
   msgOuter.id_recipient IN(1,2,3,4,5)
 AND
   rank <= 10