2013-07-04 19 views
0

我有一個SQL問題。首先,我想知道它甚至可能只使用SQL,如果不是,任何人都不知道一個好的解決方法。按訂單計算最後一小時的MySQL遞歸

我們正在建立一個網站,用戶可以投票支持視頻。
用戶可以通過短信或Facebook認證後直接在網站上投票。
我們必須製作所有視頻的頂部列表,並計算每個視頻列表上的「位置」。

到目前爲止,我們已經做了一個簡單的子查詢,像這樣的東西:

SELECT v.video_id AS id, 
    (SELECT (COUNT(*)+1) FROM videos AS v2 
     WHERE (v2.SMS_votes + v2.facebook_votes) > (v.SMS_votes + v.facebook_votes)) AS total_position 
FROM videos AS v 

SMS_votesfacebook_votes聚集領域。每種投票都有單獨的表格,每個投票的記錄,包括投票時間。

這工作得很好,位置計算......如果兩個或更多的影片具有相同的票數,他們「分享」的位置。

遺憾的是不能有任何位置共享,我們有以下規則來解決這個問題:

  • 如果2個視頻具有相同的票數,在一個更短信票數的優點
  • 如果他們也有相同數量的短信票數,有個好處
  • ,如果他們也有在過去一小時相同數量的短信票數,他們是按小時相比,有更多的短信票數在最後一小時的一個之前和遞歸的那樣,直到兩者之間有差別

是否有可能做這種遞歸排序的只是在SQL,還是必須在代碼中手動解決此?所有想法都受到歡迎。需要注意的是,這裏的性能很重要,因爲頂部列表在整個站點都被使用。

+0

你如何存儲短信票數和投票時間爲給定的視頻,在其他表?換句話說,添加一個查詢,該查詢將給定給定視頻的給定小時數的短信投票數。 – Mikhail

+0

是的。還有兩張桌子,一張用於短信投票,一張用於Facebook投票 – ZolaKt

回答

0

我不認爲用recusive計算(這可能是無限的)來執行這種排序是不可行的,但是如果你願意限制回顧的時間量,完成。

這裏有一種可能性。

SELECT video_id, 
    SMS_votes + facebook_votes AS total_votes, 
    SMS_votes, 
    COUNT(CASE WHEN time > NOW() - INTERVAL 1 HOUR THEN 1 END) AS h1, 
    COUNT(CASE WHEN time > NOW() - INTERVAL 2 HOUR THEN 1 END) AS h2, 
    COUNT(CASE WHEN time > NOW() - INTERVAL 3 HOUR THEN 1 END) AS h3 
FROM videos 
JOIN SMS_votes USING(video_id) 
GROUP BY video_id 
ORDER BY total_votes DESC, SMS_votes DESC, h1 DESC, h2 DESC, h3 DESC; 

這裏假設你有一個表稱爲SMS_votes跟蹤每個投票,以VIDEO_ID場和時間場。

對於每一個視頻,它計算的總票數,短信投票,在過去一小時的短信投票,前兩個小時,而過去三個小時。然後它會對所有這些值執行ORDER BY以獲得正確的位置。

這是相當容易擴展這包括更廣泛的時間,但你可能也想爲你回去的時間來考慮使用時間的增加範圍。例如,您首先查看過去一小時,過去一天,過去一週等等的投票情況,我懷疑這會降低您獲得相同投票的視頻的機會,而無需增加額外的計算。

SQL Fiddle example

+0

這很簡單,但不幸的是不能接受。我們不能將其限制爲僅有幾個時間間隔 – ZolaKt