从我的帖子表中的每个类别中选择最后 4 行


Select last 4 row from every category in my post table

我有一个博客应用程序的帖子表。

表结构:

post_id  post_title  post_description category_id created_time status

我想从我的表格中选择每个类别的最后 4 个帖子。我该怎么做。我正在使用mysql数据库。

您可以尝试以下查询:

我假设你的表名是BLOG

SELECT
    t.post_title,
    t.post_description,
    t.category_id,
    t.created_time
FROM
    (
        SELECT
          *,
          IF (@prev = category_id ,@cn := @cn + 1 ,@cn := 0) SL,
          @prev := category_id
        FROM blog,(SELECT @cn := 0, @prev := 0) var
        ORDER BY category_id, created_time DESC
    ) t
WHERE   t.SL < 4;

SQL 小提琴演示

备注:如果要从每个类别中获取最新的5条记录,则只需更改以下行,如下所示:

WHERE t.SL < 5;

解释:

  1. 首先根据category id对行进行排序,以便行属于同一类别的保持在一起。
  2. 然后根据created_time DESC进行排序。
  3. 现在,您得到了一个结果集,其中行的排序依据为 category_idcreated_time DESC .
  4. 现在分配一个标志值,该值将指示相应的职位在每个类别中的位置。(在本例中为此标志值 SL0开始)。如果您在同一类别下看到一行,则只需为其分配下一个值 SL。如果您在下面看到一行(i.e. new category)不同的类别,然后重置 SL0 .
  5. 执行上述操作,您最终将得到行所在的结果根据 category_id 排序,created_time DESC 以及标志值(SL)在结果集中具有相应的位置。
  6. 现在,如果您过滤标志值 (SL) 包含的那些记录小于此结果集4的值,您将获得这些记录这是每个类别中排名前4的记录之一。

以下查询涵盖了1 to 5步骤(它是给定查询中的内部查询):

SELECT
   *,
   IF (@prev = category_id ,@cn := @cn + 1 ,@cn := 0) SL,
   @prev := category_id
 FROM blog,(SELECT @cn := 0, @prev := 0) var
 ORDER BY category_id, created_time DESC;

仅此查询的演示

请检查每行的SL值。我希望你能得到它。

您可以使用 NOT EXISTS()

SELECT * FROM YourTable t
WHERE NOT EXISTS(SELECT 1 FROM YourTable s
                 WHERE t.post_id = s.post_id 
                   AND t.created_time < s.created_time
                 GROUP BY post_id
                 HAVING count(*) > 3)

我不知道每一行的独特性是什么,我假设post_id。如果它也post_title/category_id ETC,则将其添加到分组依据子句和关系条件