2016-08-05 61 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

相關問題