保留IN子查询的排序

时间:2011-10-05 14:14:09

标签: mysql sql-order-by

这应该是一个简单的,但我似乎无法让mysql玩球。

我正在尝试构建一个用户最近投票的项目列表,以便在该用户个人资料页面上使用。

我有投票表,包含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,然后是9,然后进入用户投票以进一步投入过去的项目。

4 个答案:

答案 0 :(得分: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 :(得分: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) );

答案 2 :(得分:1)

DISTINCT不是必需的,因为即使IN()子查询可能返回重复项,外部查询也只是查找这些中的匹配值,而不是1:1关系。这与JOIN行为不同,您最终可能会遇到重复的行。

这类似于说你有一个数组[1,2,2,4,5,5]并且询问来自不同数组[1,2,5,6]的哪个值在第一个数组中出现 。答案总是[1,2,5]。希望这个例子不会让人感到困惑。当我想到改进它的方法时,我会编辑它。

以前的答案提供了正确的ORDER BY

答案 3 :(得分:1)

您可以将其重写为联接:

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