2016-12-05 8 views
0

私は2つのテーブルがあります。企業の場合はbusinessesreviewsです。Mysqlベイジアンと星の評価で並べ替え

businessesテーブル:

+----+-------+ 
| id | title | 
+----+-------+ 

reviewsテーブル:

+----+-------------+---------+------+ 
| id | business_id | message | rate | 
+----+-------------+---------+------+ 

各レビューはrate(1〜5つ星)を持っている
私はBayesian Rankingに基づいて、彼らのレビュー速度で事業をソートしたいです少なくとも2つのレビューを持っているという条件で。ここで

は私のクエリです:

SELECT b.id, 
(SELECT COUNT(r.rate) as rr FROM reviews r WHERE r.business_id = b.id) as rr, 
(SELECT 
     ((COUNT(r.rate)/(COUNT(r.rate) + 2)) AVG(r.rate) + 
     (2 /(COUNT(r.rate) + 2)) 4) 
    FROM reviews r where r.business_id = b.id AND rr > 2 
) as score 
FROM businesses b 
order by score desc 
LIMIT 4 

この意志出力私は:

+------+----+------------+ 
| id | rr | score  | 
+------+----+------------+ 
| 992 | 14 | 4.31250000 | 
+------+----+------------+ 
| 237 | 3 | 4.2000000 | 
+------+----+------------+ 
| 19 | 5 | 4.0000000 | 
+------+----+------------+ 
| 1009 | 12 | 3.9285142 | 
+------+----+------------+ 

私は2つの質問があります:あなたが((COUNT(r.rate)/(COUNT(r.rate) + 2)) AVG(r.rate) + (2 /(COUNT(r.rate) + 2)) 4) FROM reviews r where r.business_id = b.id AND rr > 2)に見るように、いくつかの機能は、より多くのを実行している

  1. COUNTまたはAVGのように1回以上彼らはバックグラウンドで一度実行され、おそらくresusltをキャッシュしていますか? 1回の呼び出しごとに実行されますか?

  2. これに対応するクエリはありますが、さらに最適化されていますか?

ありがとうございます。

+0

「正しい」回答が得られますか?私は 'rr'が2番目のサブクエリに見えてはならないと思う。 –

答えて

1

私は、MySQLが複数のカウントを最適化することを望んでいますが、それは確かではありません。

ただし、サブクエリに参加するようにクエリを再編成できます。この方法では、すべての行に対して2つのサブクエリを実行していません。

SELECT b.id, 
     sub0.rr, 
     sub0.score 
FROM businesses b 
INNER JOIN 
(
    SELECT r.business_id, 
      COUNT(r.rate) AS rr , 
      ((COUNT(r.rate)/(COUNT(r.rate) + 2)) AVG(r.rate) + (2 /(COUNT(r.rate) + 2)) 4) AS score 
    FROM reviews r 
    GROUP BY r.business_id 
    HAVING rr > 2 
) sub0 
ON sub0.business_id = b.id 
ORDER BY score DESC 
LIMIT 4 

クエリはまだなく、NULLのスコアでそれらを返します。一方で、それは、唯一の2件の持つレコードを除外しますよう、ここで結果は非常にわずかに異なっていることに注意してください。私は明白な失われた演算子(つまり、AVG(r.rate)の前との前に)4)ASスコア元のクエリから残っています。

上記の考え方を使用すると、サブクエリでカウントと平均レートの両方を返すようにコードを再コードし、返されたカラムの値を計算に使用することができます。

SELECT b.id, 
     sub0.rr, 
     ((rr/(rr + 2)) arr + (2 /(rr + 2)) 4) AS score 
FROM businesses b 
INNER JOIN 
(
    SELECT r.business_id, 
      COUNT(r.rate) AS rr , 
      AVG(r.rate) AS arr 
    FROM reviews r 
    GROUP BY r.business_id 
    HAVING rr > 2 
) sub0 
ON sub0.business_id = b.id 
ORDER BY score DESC 
LIMIT 4 
+0

ご返信ありがとうございます。私はあなたの2番目のクエリを実行しようとしましたが、 'b.idが不明です.'12行目にエラーがあります。だから私はこれに変更しました。 https://codetidy.com/9750/、サブクエリはすべてrr> 2を取得 – Pars

+1

@Pars - 修正されました。サブクエリは、カウントが2以上のすべてのものを取得しますが、それはビジネステーブルに対して再び結合され、計算が実行されてスコアが計算されます。したがって、サブクエリへの結合では、2つ以下のレビューでは除外されますが、メインクエリでのORDER/LIMITでは4つの行が返されます。 – Kickstart

関連する問題