2016-08-05 7 views
0

検索結果ページの複雑な順序付けアルゴリズムを構築するのには苦労しています。検索結果は、評価とその他の値に基づいて並べ替えます。

評価(評価数、平均評価)で商品を注文したいのですが、結果ページの60-80%の間に評価を入れたいだけです。 1ページには12の項目があります。それらはページ上でランダムに配布されるべきです。

created_atフィールドなどの第2の基準として単純な注文を適用したいと考えています。

どのようにすればよいのでしょうか?

+0

*評価結果ページの60〜80%を占めるようにします。 1ページには12の項目があります。* ...あなたはf.exを望みます。最初のページには上位10個の評価項目が含まれ、2番目に最も新鮮なもの、2番目に最も評価された10と2番目の2番目の最も新鮮な項目などが含まれます(重複はありません)。または、あなたは単に 'ORDER BY rating 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つの最高の定格項目
  • すべき項目でなければなりません返さべき2回表示されないので、アイテムが最近作成され、高い評価を受けている場合は、追加アイテムが必要です。

は、これを達成するために、私は次の試み:

  1. 割り当てが作成され、頂部8のためのためにトップ4の両方であるアイテムの数を計算するのcreated_atとavg_rating列
  2. 両方に行番号を命じアイテム(私たちはこの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

関連する問題