按贝叶斯评级订购数据库结果

时间:2011-11-21 16:18:50

标签: php mysql database sorting sql-order-by

我不确定这是否可行,但在做“丑陋”的方式之前我需要确认:)

因此,“结果”是数据库中的帖子,其存储方式如下:

  • 帖子表,其中包含所有重要内容,如ID,标题,内容
  • 帖子元表,其中包含其他帖子数据,例如评分(this_rating)和投票数(this_num_votes)。该数据成对存储,该表有3列:帖子ID /键/值。它基本上是WordPress表结构。

我想要的是抽出评分最高的帖子,根据以下公式排序:

  

br =((avg_num_votes * avg_rating)+(this_num_votes * this_rating))    /(avg_num_votes + this_num_votes

我偷了here

avg_num_votesavg_rating是已知变量(每次投票都会更新),因此无需计算。

可以使用mysql查询吗?或者我是否需要获取所有帖子并使用PHP进行排序?

3 个答案:

答案 0 :(得分:2)

数据堆栈交换链接:

http://data.stackexchange.com/stackoverflow/s/2137/order-database-results-by-bayesian-rating

SELECT id,title,( AVG(this_num_votes) * AVG(this_rating) + this_num_votes * this_rating )
     / ( AVG(this_num_votes) + this_num_votes ) as br
FROM posts
LEFT JOIN (
SELECT DISTINCT post_id,
(SELECT meta_value FROM postmeta WHERE postmeta.post_id = pm.post_id AND meta_key ='this_num_votes') as this_num_votes,
(SELECT meta_value FROM postmeta WHERE postmeta.post_id = pm.post_id AND meta_key ='this_rating') as this_rating
FROM postmeta pm ) as newmeta ON posts.ID = newmeta.post_id
GROUP BY id,title,this_num_votes,this_rating
ORDER BY br DESC

答案 1 :(得分:1)

这是一个开始:

// Bayesian Rating Calc
$theItem = $_GET[’id’];
if($theItem) {
// all items votes and ratings
$result = mysql_query(”SELECT AVG(item),AVG(vote) FROM itemvotes WHERE vote>’0′ GROUP BY item”) or die(mysql_error());
$row = mysql_fetch_row($result);
$avg_num_votes = $row[0];
$avg_rating = $row[1];

// this item votes and ratings
$result = mysql_query(”SELECT COUNT(item),AVG(vote) FROM itemvotes WHERE item=’$theItem’ AND vote>’0′”) or die(mysql_error());
$row2 = mysql_fetch_row($result);
$this_num_votes = $row2[0];
$this_rating = $row2[1];

if(!$row OR !$row2)
$br = “_”;
else
$br = number_format( ((($avg_num_votes * $avg_rating) + ($this_num_votes * $this_rating))/($avg_num_votes + $this_num_votes)), 1, ‘.’ );
} // end of if item selected

答案 2 :(得分:1)

我更改了已接受答案的数据和查询。

该数据现在是来自5星评级系统的数据样本 该功能现在可以正确使用所有帖子的平均值。

区别在于计算那些平均值,而不是PHP,它们是在SQL中计算的,用于答案。

你可以在SQL Fiddle上看到它:http://sqlfiddle.com/#!9/84d8b/2/2

更新的查询

新小提琴:http://sqlfiddle.com/#!9/3cdfe/1/2

SET @avg_total_votes  := (SELECT AVG(meta_value) FROM postmeta WHERE meta_key ='this_num_votes');
SET @avg_total_rating := (SELECT AVG(meta_value) FROM postmeta WHERE meta_key ='this_rating');

SELECT  posts.ID,
        posts.title, 
        getmeta_votes.meta_value AS votes,
        getmeta_rating.meta_value AS rating,
        ( ( (@avg_total_votes * @avg_total_rating) + (getmeta_votes.meta_value * getmeta_rating.meta_value) ) / ( @avg_total_votes + getmeta_votes.meta_value ) ) AS factor
FROM posts
LEFT JOIN postmeta AS getmeta_votes  ON posts.ID = getmeta_votes.post_id  AND getmeta_votes.meta_key  = 'this_num_votes'
LEFT JOIN postmeta AS getmeta_rating ON posts.ID = getmeta_rating.post_id AND getmeta_rating.meta_key = 'this_rating'
WHERE NOT getmeta_votes.meta_value = 0 AND NOT getmeta_rating.meta_value = 0
ORDER BY factor DESC;

我发现这个查询构造要快得多,前一个在2,000+帖子数据集(1,000,000 + wp_postmeta行)上工作了2个小时,直到终止。

这个运行时间为0.04秒。