2015-12-18 56 views
1

我有兩個表,創建這樣(只相關的顯示信息)排序按行排在其他表填充一個「熱門」名單

CREATE TABLE levels 
(
    id INT(6) UNSIGNED AUTO_INCREMENT, 
    gameid INT(6), 
    created DATETIME, 
    PRIMARY KEY(id,gameid) 
) 

CREATE TABLE votes 
(
    levelid INT(6) NOT NULL REFERENCES levels(id), 
    vote TINYINT(1), 
    date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY(levelid) 
) 

用戶獲得的水平(+1或投票 - 1),從而創建一個回到某個級別的投票記錄。

我想用數據來做到這一點,非語法:

SELECT * FROM levels ORDER BY 
(select sum(vote) from votes where votes.levelid=levels.id and date is within the last week) 

我怎麼可能把它轉換成一個合法的MySQL查詢?我所嘗試的一切都給了我一個非常神祕的錯誤信息(「出錯了!查看手冊!」),我只是mySQL的高級初學者。

我們的目標是返回我的所有關卡,並按照上週有最佳選票的人進行排序......這樣,新關卡將會變得越來越流行,而更老的關卡將會脫落。

在此先感謝!

編輯:

所以這裏的預期結果的例子: 這裏是我的數據(在英文中爲清楚起見):

級別:
LEVEL1(ID = 1)
LEVEL2(ID = 2)

票:
+1 LEVEL1兩天前
+1 LEVEL1十天前
+1 LEVEL120天前
+1 LEVEL2一天前
+1 LEVEL2三天前
-1 LEVEL230天前

所以我可以做這樣的查詢:

SELECT * FROM LEVELS ORDER BY (select sum(vote) from votes where levelid=levels.id) 

而且這會使我獲得LEVEL1的+3和LEVEL2的+1。

但是,在過去的七天裏,我應該看到LEVEL1爲+1,LEVEL2爲+2,因此首先返回LEVEL2。

而且,我得到的總體思路是 「爲了通過(選擇...」 將是相當緩慢

還有一個編輯:

此查詢的工作:

SELECT * FROM levels ORDER BY (SELECT SUM(vote) FROM votes WHERE levelid=levels.id AND votes.date>=(CURDATE() - INTERVAL 7 DAY)) DESC 

。 ..但這是做這種事情的最好方法嗎?

+0

我會建議添加一些示例數據(足以說明意圖)和預期結果。 (使用[edit]。) –

+0

好的,我將編輯該問題。我試圖把數據放在這裏,但格式化使其不可讀。 – Raptisoft

+0

與您的問題無關,但我認爲您需要在此處爲​​投票創建不同的主鍵;因爲每個級別只能有1票。 –

回答

0

你可以用左連接做到這一點:

SELECT levels.*, coalesce(sum(votes.vote),0) as total_vote 
FROM levels 
LEFT JOIN votes ON votes.levelid = levels.id 
WHERE votes.date >=(CURDATE() - INTERVAL 7 DAY)) 
GROUP BY levels.id 
ORDER BY coalesce(sum(votes.vote),0) desc; 

這裏的合併確保未投票的級別獲得分數(而不是空值)並正確排序。

+0

安德魯,這是比我上面提到的(選擇)更快的方法嗎?這個查詢可能會經常遇到。 – Raptisoft

+0

是的,SQL引擎被優化來執行這種連接。 SQL引擎可以在一個「步驟」中執行連接的所有工作。你的查詢,在你通過一個子SELECT進行排序時,並不是非常高效的,因爲它包含了所謂的「相關子查詢」。也就是說,SQL引擎需要爲主SELECT返回的每一行執行額外的SELECT。 –

+0

Andrew,我試圖將我的代碼轉換爲此連接版本,並且遇到了一些語法問題。 我發送該數據: \t SELECT coalesce(sum(votes.vote),0)as total_vote,levels.id,levels.name,levels.rating,levels.updated,users.username,users.countrycode,levels。 playcount,levels.wincount,comments FROM levels,users WHERE gameid = 1 AND users.id = levels.authorid LEFT JOIN votes ON votes.levelid = levels.id WHERE votes.date> =(CURDATE() - INTERVAL 7 DAY)) GROUP BY levels.id ORDER BY coalesce(sum(votes.vote),0)DESC LIMIT 0,10 我得到一個錯誤'near LEFT JOIN ...' 我認爲這是「哪裏? – Raptisoft