2011-08-13 48 views
3

我有一個SQL表看起來像這樣所謂的「上崗」:MySQL:通過從另一個表中使用兩個計數來排序?

id | user 
-------------------------------- 
0 | tim 
1 | tim 
2 | bob 

而另一家名爲「票」,用於存儲無論是在「上崗」表上的職位upvotes或downvotes:

id | postID | type 
-------------------------------- 
0 | 0  | 0 
1 | 2  | 1 
2 | 0  | 1 
3 | 0  | 1 
4 | 3  | 0 

在此表中,「類型」是downvote的0或upvote的1。

我該如何去訂閱「tim」發佈帖子的數量(upvotes - downvotes)的帖子?

+0

從本質上講,蒂姆的第一篇文章('ID = 0')有2個upvotes和1個downvote,這樣的比分是1。雖然他的第二個職位('ID = 1')沒有任何選票,因此得分爲零。所以我們的目標是,當這些被選中('SELECT * FROM posts WHERE user ='tim'ORDER BY DESC')時,我們可以按某種方式排序,而不需要在帖子表中添加一個新字段 – Tomas

回答

3
SELECT 
    p.id, 
    p.user, 
    SUM(v.type * 2 - 1) AS votecount 
FROM posts p 
    LEFT JOIN votes v ON p.id = v.postID 
WHERE p.user = 'tim' 
GROUP BY p.id, p.user 
ORDER BY votes DESC 

UPDATE - pv解釋。

在該查詢中,pv別名分別的,postsvotes。別名本質上是一個替代名稱,它只在聲明它的語句的範圍內(在本例中爲SELECT語句)定義。不僅表格可以有別名,而且也可以有列。在此查詢中,votecount是由SUM(v.type * 2 - 1)表達式表示的列的別名。但目前我們只談論桌子。

在繼續關於表別名的解釋之前,我將簡要解釋爲什麼您可能需要在列名前加上表名,如posts.id而不是id。基本上,當查詢引用多個表時,就像在這種情況下一樣,您可能會發現始終將列名與相應的表名前綴相當有用。這樣,當你重新訪問一箇舊腳本時,你總是可以知道哪個列屬於哪個表,而不必查找引用表的結構。此外,它是強制性的在包含表引用時忽略它會造成該列所屬的表的歧義。 (在這種情況下,引用id列不必引用posts表並創建模棱兩可的情況,因爲每個表都有了自己的id。)

現在,一個龐大而複雜的查詢可能是困難的,當你寫出完整的閱讀列名之前的表名。這是短的別名派上用場:他們使查詢更容易閱讀和理解,雖然我已經知道並非所有人都同意這個觀點,所以你應該自己判斷:this question包含兩個版本查詢,其中一個使用長命名錶引用,另一個使用短名稱引用,以及一個意見(在對其中一個答案的評論中)爲什麼別名不適用。

無論如何,在這個特定查詢中使用短表別名可能並不像在一些更復雜的語句中那樣有益。只是當查詢引用多個表時,我習慣於對錶進行別名。

This MySQL documentation article包含MySQL中用於別名表的官方語法(實際上與標準SQL中的相同)。

+0

我喜歡你的操作來確定投票價值 - 它的可愛,漂亮 –

+0

@Derek:謝謝。但是,如果其他類型存在/出現,它可能會中斷。但是我將它保留下來,只是作爲更傳統(可靠)的CASE/IF()方法的替代方案。 –

+0

@Andiry M:對不起,我正在學習SQL,如果能爲我澄清這些單個字母('p'和'v'),我會非常感激,他們是否添加了一種快速引用這些表的方法?你可以將我鏈接到教程或告訴我他們被稱爲什麼?謝謝。 – Tomas

1

沒有測試,但應該工作:

select post.id, sum(if(type = 0, -1, 1)) as score 
from posts join votes on post.id = votes.postID 
where user = 'tim' 
group by post.id 
order by score 

你打算SO同意? ;-)

1

編輯:我砍掉了子查詢,因爲在mysql中它是不必要的。最初的查詢是可移植的,但對於MySQL不是必需的。

select 
    p.id, SUM(case 
       when v.type = 0 then -1 
       when v.type = 1 then 1 
       else 0 end) as VoteCount 
from 
    posts p 
    left join votes v 
     on p.id = v.postid 
where 
    p.[user] = 'tim' 
group by 
    p.id 
order by 
    VoteCount desc 
+0

嗨,德里克,爲什麼子查詢? – TMS

+0

我更新了它 - 我更熟悉mssql,所以我寫了一些可移植的東西。更新的查詢應該更適合於mysql –

+0

@Derek:那麼您可能還不知道SQL Server也支持在ORDER BY中引用別名。對於舊的和跨平臺的CASE方法+1,但'@' -names應該可以替換爲'正常'的名稱。 –

相關問題