代码之家  ›  专栏  ›  技术社区  ›  Ilja KO

有条件地对查询结果排序

  •  0
  • Ilja KO  · 技术社区  · 6 年前

    我在Rails应用程序中有帖子和评论。我想显示按最近活动排序的帖子,这意味着带有最近评论的帖子排在第一位。

    Post.left_outer_joins(:comments).
    order('comments.created_at DESC, posts.created_at DESC').
    uniq
    

    如您所见,它连接两个表,对结果进行排序,并从中选择唯一的条目

    • 如果帖子没有评论,那么这些帖子会以降序出现,但是我希望帖子按照最近活动的顺序出现。

    就像一个论坛,在用户最近的活动之后对他们的帖子进行排序

    我想合并这些列 comments.created_at posts.created_at 进入纵队 posts.u创建于 值为:

    • comments.u创建于 如果不为空,则为
    • posts.u创建于

    然后对整个查询进行排序 posts.u创建于

    3 回复  |  直到 6 年前
        1
  •  1
  •   khaled_gomaa    6 年前

    在这种情况下,您可以按两者的最大值进行排序。

    Post.left_outer_joins(:comments).
    order('GREATEST(comments.created_at, posts.created_at) DESC').
    uniq
    
        2
  •  0
  •   Ilja KO    6 年前

    我刚用Ruby做了:

    @posts = Post.where(category: params[:category])
    @posts.each do |p|
      p.created_at = p.comments.count == 0 ? p.created_at : p.comments.last.created_at
    end
    @posts = @posts.sort_by { |k| k[:created_at] }.reverse
    @posts = @posts.paginate(page: params[:page])
    
        3
  •  0
  •   dcangulo    6 年前

    应用程序/模型/post.rb

    class Post < ApplicationRecord
      has_many :comments
    end
    

    app/models/comment.rb应用程序

    class Comment < ApplicationRecord
      belongs_to :post
    end
    

    数据库/架构.rb

    ActiveRecord::Schema.define(version: 2018_09_20_081230) do
    
      create_table "comments", force: :cascade do |t|
        t.text "comment_content"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
        t.integer "post_id"
      end
    
      create_table "posts", force: :cascade do |t|
        t.string "post_title"
        t.text "post_content"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
      end
    
    end
    

    Post.includes(:comments).order('comments.created_at DESC')
    

    测试环境:

    • 红宝石5.2.1

    更新

    Post.joins('LEFT JOIN comments ON comments.post_id = posts.id').group('posts.id').order('COALESCE(MAX(comments.created_at), posts.created_at) DESC')
    

    或者

    Post.find_by_sql('SELECT posts.* FROM posts LEFT JOIN comments ON comments.post_id = posts.id GROUP BY posts.id ORDER BY COALESCE(MAX(comments.created_at), posts.created_at) DESC')