2011-06-05 27 views
3

下令在我的PHP應用程序,我的文章一個MySQL表,有以下欄目:混合不同類別的結果,按分數在MySQL

article_id articletext category_id score 

每篇文章都有它是基於怎樣流行的計算分數它是,屬於一個特定的類別(有大約10個類別可用)

我的問題是:如何執行一個查詢,返回最高得分的文章,而按類別交替,以便如果可能,類別文章連續返回。 例如,如果最高得分製品具有的分數:100返回集將是這樣的:

article_id articletext category_id score 
----------------------------------------------------- 
142   <.....>  5    100 
153   <.....>  3    97 
119   <.....>  5    99 
169   <.....>  2    93 
121   <.....>  7    89 
197   <.....>  2    92 
. 
. 
. 

第一(幼稚)溶液附帶記正在執行10種選擇(1爲每個類別),訂購他們通過分數降序,然後在PHP級別,在每個返回的數據集之間交替,一次選取一個結果,並將它們組合在一個新數組中。

有沒有更有效的方法來實現這一目標?如果可能的話,在MySQL級別

+1

有趣的問題 - 有點非正統的要求,但有趣。純粹基於SQL的解決方案可能會非常棘手。 – 2011-06-05 18:06:57

回答

1

去獲得前20名。如果他們不符合要求,做一個額外的查詢來獲取缺失的部分。您應該能夠在查詢數量和每個返回的行數之間找到一些平衡點。

我有100多個,它可以滿足90%的時間要求,比10個單獨的查詢更便宜,更快。

如果是SQL服務器,我可以幫助更多...

其實,我有另一個想法。每5分鐘運行一個進程計算列表並將其緩存在表中。使DML針對相關表將使緩存失效,以便在重新填充(可能是文章被刪除)之前不使用它。如果緩存無效,那麼您會後退計算它,並可以使用它來重新填充緩存。

戰略性地更新緩存列表可能是可能的,而不是重新計算它。但這可能是一個真正的挑戰。

這應該有助於提高查詢速度並減少數據庫的負載。如果您的文章列表已過期5分鐘,那應該沒什麼關係。哎呀,即使1分鐘也可以工作。

+0

是啊,我就是這麼做的 – Alexandros 2011-06-05 18:38:33

+0

@Alex增加了新的想法。 – ErikE 2011-06-05 18:58:46

0

您的天真解決方案正是我所要做的。

+0

這個問題是每次創建10個查詢而不是1個,這個功能很可能會在我們的網站上頻繁使用(大多數情況下),所以這可能會增加很多偷聽 – Alexandros 2011-06-05 18:16:59

+0

佈局的好處是什麼'暗示?爲什麼不按照分數排序,並用它來完成?我會被你所描述的佈局混淆。 – 2011-06-05 20:00:51

1

僅供學習之用。我做了三個類別的測試。我不知道這個查詢如何在大型記錄集上運行。

select * from (
(select @r:[email protected]+1 as rownum,article_id,articletext,category_id,score 
from articles,(select @r:=0) as r 
where category_id = 1 
order by score desc limit 100000000) 
union all 
(select @r1:[email protected]+1,article_id,articletext,category_id,score 
from articles,(select @r1:=0) as r 
where category_id = 2 
order by score desc limit 100000000) 
union all 
(select @r2:[email protected]+1,article_id,articletext,category_id,score 
from articles,(select @r2:=0) as r 
where category_id = 3 
order by score desc limit 100000000) 
) as t 
order by rownum,score desc