2011-10-05 68 views
2

這應該是一個容易的,但我似乎無法讓mysql玩球。保留IN子查詢的排序

我正在嘗試構建用戶最近投票的項目列表,以便在該用戶個人資料頁面上使用。

我有票的表,包含UID(INT),項目(INT),時間戳(INT)

和項目表中的ID字段中票表中的項目字段匹配。

我最初的查詢是

SELECT * FROM projects WHERE id IN(SELECT project FROM votes WHERE uid=x ORDER BY timestamp DESC); 

這給出了一個正確的列表,但排序混亂。我也意識到我忘記了將DISTINCT項目添加到子查詢中,但由於某種原因,它無論如何都給出了不同的項目。

SELECT project FROM votes WHERE uid=x ORDER BY timestamp DESC; 

本身給出正確的順序,但只要我從中查詢,排序就被丟棄。

我不明白嵌套語句是如何工作的,是否有人可以幫忙,並解釋爲什麼DISTINCT關鍵字不必從投票表中獲得不同的項目ID?!

請求示例;

投票表包含個人投票,所以如果用戶爲項目投票三次,它可能看起來像這樣;

uid  project timestamp 
34  9   10984 
34  9   11093 
34  9   11309 

如果用戶(在本例中34),然後投給不同的項目中,票表現在會是什麼樣子;

uid  project timestamp 
34  9   10984 
34  9   11093 
34  9   11309 
34  21   12612 

指示9和21然後用於查詢項目表。例如,項目表可能包含;

id  name   description 
9  Project A  This is project A. 
21  Project B  This is project B. 

我想要的是用戶最近投票的項目列表。因此,在這種情況下,我想從項目表中依次獲取項目21和項目9,然後將項目21和項目9投入到用戶投票進入過去的項目中。

+2

你能提供一些示例數據和所需的輸出?在這之後我很難過。 – RedFilter

回答

2

我會在這裏使用連接而不是子查詢。

SELECT p.* 
    FROM projects p 
     INNER JOIN votes v 
      ON p.id = v.project 
    WHERE v.uid = x 
    ORDER BY v.timestamp DESC; 
1

嘗試ORDER BY FIELD - 是這樣的:

SELECT * FROM projects WHERE id IN(SELECT project FROM votes WHERE uid=x ORDER BY timestamp DESC) ORDER BY FIELD(id, (SELECT project FROM votes WHERE uid=x ORDER BY timestamp DESC)); 
1

DISTINCT是沒有必要的,因爲即使IN()子查詢可以返回重複,外部查詢僅僅是尋找那些之間的匹配值,而不是1:1的關係。這與JOIN行爲不同,您可能最終得到重複的行。

它類似於說你必須從不同陣列的值的[1,2,5,6]第一陣列中發生的任何地方一個陣列[1,2,2,4,5,5],並要求。答案總是[1,2,5]。希望這個插圖不會更混亂。當我想到改進方法時,我會對其進行編輯。

上一個答案提供了正確的ORDER BY

+0

我明白謝謝你解釋,我已經使用了多年的mysql,並完全避免了連接。也許我應該學習他們的工作方式! – lynks

+0

@lynks絕對你應該學習'JOIN's。根據表的大小,一個'JOIN'可以比IN()子查詢快幾個數量級。 –

1

您也可以重寫此爲連接:

SELECT DISTINCT projects.* FROM projects 
    JOIN votes ON projects.id = votes.project    
    ORDER BY timestamp DESC