这应该是一个简单的,但我似乎无法让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,然后进入用户投票以进一步投入过去的项目。
答案 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