Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.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
MySQL为每个类别选择前N行_Mysql - Fatal编程技术网

MySQL为每个类别选择前N行

MySQL为每个类别选择前N行,mysql,Mysql,我正在尝试从每个类别中获取最新的前2行,这可以在以后进行缩放,因此我可能会获取前4行,而不是前2行 这是我的桌子的样子 Id | category_id | created_at ------ | ----------- ---------- 1 | 1 | 2017-12-01 2 | 2 | 2017-12-02 3 | 4 | 2017-12-03 4 | 2

我正在尝试从每个类别中获取最新的前2行,这可以在以后进行缩放,因此我可能会获取前4行,而不是前2行

这是我的桌子的样子

  Id   | category_id | created_at
------ | -----------   ----------
   1   |      1      | 2017-12-01
   2   |      2      | 2017-12-02
   3   |      4      | 2017-12-03
   4   |      2      | 2017-12-04
   5   |      1      | 2017-12-05
   6   |      1      | 2017-12-06
   7   |      3      | 2017-12-07
   8   |      4      | 2017-12-08
   9   |      4      | 2017-12-09
   10  |      3      | 2017-12-10
   11  |      5      | 2017-12-11
我希望根据列ID处创建的_获取最新的2行,因此我希望输出类似于

      Ids     
    ------ 
       5   
       6   
       2   
       4   
       7
       10
       8
       9
       11
我在做类似的事情

select * from table
inner join (
    select * from table
    order by category_id, created_at
    limit 2
) as tb
on tb.id = table.id and tb.category_id = table.category_id
很明显,它不起作用,只是想分享我到目前为止取得的成果。 在MySQL中有这样做的方法吗

编辑

我真的这么做了,而且还挺管用的

SELECT *
   FROM
     (SELECT *, 
                  @count := IF(@current_category = category_id, @count + 1, 1) AS count,
                  @current_category := category_id 
       FROM table
       ORDER BY category_id, created_at DESC
     ) ranked
   WHERE count <= 2;

在MySQL中,这比它应该的更痛苦。可能最简单的方法是使用变量:

select t.*
from (select t.*,
             (@rn := if(@c = category_id, @rn + 1,
                        if(@c := category_id, 1, 1)
                       )
             ) as rn
      from t cross join
           (select @rn := 0, @c := -1) params
      order by category_id, created desc
     ) t
having rn <= 2;

在MySQL中,这比它应该的更痛苦。可能最简单的方法是使用变量:

select t.*
from (select t.*,
             (@rn := if(@c = category_id, @rn + 1,
                        if(@c := category_id, 1, 1)
                       )
             ) as rn
      from t cross join
           (select @rn := 0, @c := -1) params
      order by category_id, created desc
     ) t
having rn <= 2;

我会这样说:

select * from table group by category_id order by created_at limit 2

我的mySql技能有点生疏,但这个或它的概念应该可以解决这个问题。

我会选择这样的方式:

select * from table group by category_id order by created_at limit 2

我的mySql技能有点生疏,但这个或它的概念应该可以解决问题。

可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的问题我已经编辑了上面的问题,并且成功了,你的答案也有点类似于我的答案。谢谢你的回答。你的答案不一定有效,因为你设置了变量,然后在不同的表达式中使用它们。MySQL不保证select中表达式的求值顺序。我已经编辑了上面的问题,它成功了,您的答案也与我的类似。谢谢你的回答。你的答案不一定有效,因为你设置了变量,然后在不同的表达式中使用它们。MySQL不保证select中表达式的求值顺序。这只会从created_at排序的整个结果中获得前2行,因此它将返回前2个项目。我想要的是从created_at排序的每个类别中获得前2行。因此,如果我有多个类别,您的查询将获得整个结果中的前2行,而不考虑按created_at排序的类别。当然,我记得这将限制每个组的结果,我的错误是,这将只获得created_at排序的整个结果中的前2行,因此它将准确返回前2行itemsyeah,我想要的是从我创建的每个类别中获得前2名。因此,如果我有多个类别,您的查询将从整个结果中获得前2名,当然不考虑按created_排序的类别。我记得这将限制每个组的结果,我的错误