按列分组,结果限制并按另一列轨道排序
Posted
技术标签:
【中文标题】按列分组,结果限制并按另一列轨道排序【英文标题】:Group by column, result limit and sort by another column rails 【发布时间】:2022-01-11 20:45:10 【问题描述】:假设我们有模型ItemStatistic
和Book
。
ItemStatistic
示例记录:
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:[,,]
【问题讨论】:
【参考方案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 的结果大小应为
【讨论】:
以上是关于按列分组,结果限制并按另一列轨道排序的主要内容,如果未能解决你的问题,请参考以下文章