2016-08-05 104 views
0

我正努力为搜索结果页面构建复杂的排序算法。根据评分和其他值排序的搜索结果

我想按评级(评分数,平均评分)排序我的项目,但我只希望评分在60-80%的结果页面之间。一页有12个项目。它们应该随机分布在一个页面上。

我想申请简单的顺序作为次要标准,如​​created_at字段。

有没有人有一个想法如何做到这一点?

+0

*我只希望评分在60-80%的结果页面之间。一页有12项。* ...所以你想要f.ex.第一页包括评分最高的10个项目和最新的2个,第二个包括第二个最高评分10和第二个最新鲜项目等(显然没有重复)?或者你只需​​要'ORDER BY评分DESC,created_at ASC'? (但这似乎是相当明显的问题)。 – pozs

+0

第一个确实。约有8项结果与评分和4项结果新鲜。优选混合。 – Karens

回答

0

我最终使用了一个解决方案,其中包括未评级项目的机会最终在评分项目的中间。该算法的想法如下:

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

我你的要求,解释是:

  • 12个总笔数返回
  • 4项应该是最近创建的项目
  • 其余8应该是收视率最高的项目
  • 项目应不会出现两次,因此如果某件商品是最近创建的且评分较高,我们需要额外的商品

为了实现这一目标,我试过如下:

  1. 指定命令行号的created_at和AVG_RATING列
  2. 都计算出在双方的前4物品的数量创造和8强项目(我们称之为num_duplicates)
  3. 增加的高度评价的项目总数由num_duplicates返回

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 
+0

对不起,我没有回应你的建议。我需要一些时间来了解您的解决方案。当我最终实现它时,我意识到解决方案太复杂,查询耗时太长。在我的答案中查看我最终使用的解决方案。 – Karens