Retrieve 2 last posts for each category

后端 未结 2 1703
春和景丽
春和景丽 2020-12-10 22:47

Lets say I have 2 tables: blog_posts and categories. Each blog post belongs to only ONE category, so there is basically a foreign key between the 2 tables here.

I wo

相关标签:
2条回答
  • 2020-12-10 23:19
    SELECT  p.*
    FROM    (
            SELECT  id,
                    COALESCE(
                    (
                    SELECT  datetime
                    FROM    posts pi
                    WHERE   pi.category = c.id
                    ORDER BY
                            pi.category DESC, pi.datetime DESC, pi.id DESC
                    LIMIT 1, 1
                    ), '1900-01-01') AS post_datetime,
                    COALESCE(
                    (
                    SELECT  id
                    FROM    posts pi
                    WHERE   pi.category = c.id
                    ORDER BY
                            pi.category DESC, pi.datetime DESC, pi.id DESC
                    LIMIT 1, 1
                    ), 0) AS post_id
            FROM    category c
            ) q
    JOIN    posts p
    ON      p.category <= q.id
            AND p.category >= q.id
            AND p.datetime >= q.post_datetime
            AND (p.datetime, p.id) >= (q.post_datetime, q.post_id)
    

    Make an index on posts (category, datetime, id) for this to be fast.

    Note the p.category <= c.id AND p.category >= c.id hack: this makes MySQL to use Range checked for each record which is more index efficient.

    See this article in my blog for a similar problem:

    • MySQL: emulating ROW_NUMBER with multiple ORDER BY conditions
    0 讨论(0)
  • 2020-12-10 23:22

    Check out this MySQL article on how to work with the top N things in arbitrarily complex groupings; it's good stuff. You can try this:

    SET @counter = 0;
    SET @category = '';
    
    SELECT
      *
    FROM
    (
      SELECT
        @counter := IF(posts.category = @category, @counter + 1, 0) AS counter,
        @category := posts.category,
        posts.*
        FROM
          (
          SELECT
            *
            FROM test
            ORDER BY category, date DESC
          ) posts
    ) posts
    HAVING counter < 2
    
    0 讨论(0)
提交回复
热议问题