【问题标题】:Group by column, result limit and sort by another column rails按列分组,结果限制并按另一列轨道排序
【发布时间】:2022-01-11 20:45:10
【问题描述】:

假设我们有模型ItemStatisticBookItemStatistic示例记录:

  item_id: 15,
  book_id: 3,
  score: 0.25192368e4,

书籍示例:

  id: 3,
  title: 'Harry Potter',

我们需要将ItemStatistic 记录按item_id 分组,然后按score 对每个item_id 键的结果进行排序,并按3 限制每个item_id 键的值的数量并返回not @ 987654332@ 记录但Book。 示例:

{15: [{id: 3, title: 'Harry Potter'}, {id: 4, title: 'The Chronicles of Narnia'},...], 2: [...]}

{1: [{},{},{}], 2: [{},{},{}], 3:[{},{},{}]}

【问题讨论】:

    标签: sql ruby-on-rails ruby


    【解决方案1】:

    如果我正确理解了这个愿望,以下应该可以工作

    item_statistics_table = ItemStatistic.arel_table 
    filter = Arel::Table.new('filtered_results')
    sub_query = item_statistics_table.project(
      item_statistics[Arel.star],
      Arel.sql('ROW_NUMBER() OVER(
                  PARTITION BY item_statistics.item_id 
                  ORDER BY item_statistics.score DESC
                )').as('row_num')
    )
    
    query = Arel::Nodes::As.new(sub_query, Arel.sql(filter.name))
    
    join_clause = Arel::Nodes::InnerJoin.new(
        query,
        Arel::Nodes::On.new(
          Book.arel_table[:id].eq(filter[:book_id])
            .and(filter[:row_num].lteq(3))
        )
      )
    
    Book
     .select(Book.arel_table[Arel.star],filter[:item_id])
     .joins(join_clause)
     .group_by(&:item_id)
    

    这应该会产生以下 SQL:

    SELECT 
        books.*,
        filtered_results.item_id
    FROM 
        books 
        INNER JOIN (
          SELECT 
            item_statistics.*,
            ROW_NUMBER() OVER(
              PARTITION BY item_statistics.item_id 
              ORDER BY item_statistics.score DESC
            ) as row_number
          FROM 
            item_statistics
        ) AS filtered_results ON books.id = filtered_results.book_id 
                AND filtered_results.row_number <= 3
    

    然后我们按item_id(虚拟属性)对所有书籍进行分组,所以结果是

    {1 => [Book,Book,Book], 2 => [Book,Book,Book]}
    

    Array 的结果大小应为

    【讨论】:

      猜你喜欢
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 2018-10-23
      • 2020-12-14
      • 1970-01-01
      相关资源
      最近更新 更多