根据评级和其他值搜索结果排序

时间:2016-08-05 10:14:27

标签: sql postgresql sorting rails-postgresql postgresql-9.5

我正在努力为搜索结果页面构建一个复杂的排序算法。

我想通过评分(评分计数,平均评分)来订购我的商品,但我只希望评级在结果页面的60-80%之间。一页有12个项目。它们应该在页面上随机分发。

我想将简单排序应用为辅助条件,例如created_at字段。

有人知道该怎么做吗?

2 个答案:

答案 0 :(得分:0)

我对您的要求的解释是:

  • 返回12件商品
  • 4项应该是最近创建的项目
  • 其余8项应为评分最高的项目
  • 项目不应出现两次,因此如果最近创建了一个项目且评价很高,我们将需要一个额外的项目

为了实现这一目标,我尝试了以下方法:

  1. 将已排序的行号分配给created_at和avg_rating列
  2. 计算创建前4名和项目前8名的项目数量(我们称之为num_duplicates)
  3. 增加num_duplicates
  4. 返回的高评价项目总数

    SQL Fiddle Here

        select *
        from 
        (
          select a.*,
                 sum( 
                    /* We want the total number of items that meet both criteria */
                    /* For every one of these items, we want to include an extra row */
                    case when created_row_num <= 4 and rating_row_num <= 8 
                     then 1 
                     else 0 
                   end ) over() as num_duplicates
          from (
            select  ratings.*,
                    row_number() over( order by created_at desc ) as created_row_num,
                    row_number() over( order by avg_rating desc ) as rating_row_num
            from    ratings
          ) as a
        ) as b
        where   created_row_num <= 4
                /* Get top 8 by rating, plus 1 for every record that has already been selected by creation date */
                or rating_row_num <= 8 + num_duplicates
    

答案 1 :(得分:0)

我最终使用了一种解决方案,其中包括未评级商品最终会在评级商品中间结束的可能性。该算法的思想如下:

ORDER BY
CASE WHEN rating IS NOT NULL OR RANDOM() < 0.0x THEN 1 + RANDOM()ELSE RANDOM() END 
DESC NULLS LAST