MySQL:从另一个表中使用两个计数进行排序?

时间:2011-08-13 01:46:40

标签: mysql sql sql-order-by

我有一个看起来像这个名为“posts”的sql表:

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

另一个叫“投票”,在“帖子”表中的帖子中存储赞成票或者票数:

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

在此表中,'type'为0表示downvote或1表示upvote。

如何根据帖子的(upvotes - downvotes)数量按“蒂姆”订购帖子?

3 个答案:

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

更新 - pv解释。

在此查询中,pv分别是别名postsvotes。别名本质上是一个替代名称,它仅在声明它的语句范围内定义(在本例中为SELECT语句)。不仅表可以有别名,还有列。在此查询中,votecountSUM(v.type * 2 - 1)表达式所代表的列的别名。但目前我们只讨论表格。

在继续解释表别名之前,我将简要解释为什么您可能需要为表名添加前缀,例如posts.id而不是id。基本上,当查询引用多个表时,就像在这种情况下一样,您可能会发现始终使用相应的表名称为列名添加前缀非常有用。这样,当您重新访问旧脚本时,您始终可以告诉哪个列属于哪个表,而无需查找引用的表的结构。此外,强制在省略它时包含表引用会产生关于列所属的表的歧义。 (在这种情况下,引用id列而不引用posts表确实会产生不明确的情况,因为每个表都有自己的id。)

现在,当您在列名称之前写出完整的表名时,可能很难读取大而复杂的查询。这就是(短)别名派上用场的地方:它们使查询更容易阅读和理解,虽然我已经知道并非所有人都有这种观点,所以你应该自己判断:this question包含两个同一查询的版本,一个具有长命名的表引用,另一个具有短名称的查询,以及一个意见(在对其中一个答案的评论中)为什么别名不合适。

无论如何,在这个特定查询中使用短表别名可能不如在一些更复杂的语句中那样有益。只是当查询引用多个表时,我习惯于对表进行别名。

This MySQL documentation article包含MySQL中别名表的官方语法(实际上与标准SQL中的相同)。

答案 1 :(得分: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

你打算同意吗? ; - )

答案 2 :(得分: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