【问题标题】:mySQL Query design - calculating a vote score for multiple content itemsmySQL 查询设计 - 计算多个内容项的投票分数
【发布时间】:2011-10-06 16:00:43
【问题描述】:

我有一个结构如下的内容项表

|  contentid |   message     |    categoryid  |  userid  |    dateadded | etc.. 
     15          foo bar            3             4           somedate
     16          more foo bar       3             4           somedate
     16          foo stuff          3             4           somedate

还有一个投票表,其中方向 = 1 = 赞成票,= 2 表示反对票。

|  voteid   |  contentid |  userid  |  direction |    dateadded
    7             15          4            1           some date
    8             15          6            1           some date
    9             15          17           2           some date

我想选择一组内容项,在末尾有一个附加列,其根据投票表中的投票计算得出的分数。

以前,我在内容表中附加了一个“分数”列,每次投票时,它都会更新其分数。这样做是为了让我不必有更复杂的查询来计算每个 SELECT 的分数,但我现在想更改它。

这个投票表是不久前设计的,所以如果将所有投票值更改为 1 或 2 以外的值(可能是 -1 表示反对票)会更容易,我将更新整个表。

查询将提取所有内容项,每个内容项在计算列中都有一个分数?

【问题讨论】:

    标签: mysql calculated-columns


    【解决方案1】:

    假设投票“方向”代表赞成票和反对票:

    SELECT i.contentid, 
           SUM(CASE WHEN v.direction = 1 THEN 1
                    WHEN v.direction = 2 THEN -1
                    ELSE 0 END) AS Votes
        FROM items i
            LEFT JOIN votes v
                ON i.contentid = v.contentid
        GROUP BY i.contentid
        HAVING SUM(CASE WHEN v.direction = 1 THEN 1
                    WHEN v.direction = 2 THEN -1
                    ELSE 0 END) > -3
    

    【讨论】:

    • 谢谢乔。如果我在 WHERE 子句中使用这个新的“投票”计算列,它会抱怨它不知道“投票”是什么(例如,选择大于 -3 的内容)。在这里声明后如何引用计算列?
    • @Barfoon:您可以使用HAVING 子句对其进行测试。我会更新答案。
    • 谢谢。在这种情况下,您必须执行两次SUM
    • 是的。不能在having子句中引用列别名Votes
    • +1 @barfoon:我猜mysql足够聪明,可以执行SUM一次,无论如何。另请注意,如果您将投票方向列更改为使用自然的 -1 表示反对票,则可以消除 CASE
    【解决方案2】:
    SELECT
      items.*,
      SUM(direction = 1) - SUM(direction = 2) AS score
    FROM items
    LEFT JOIN votes USING (contentid)
    GROUP BY contentid
    

    之所以有效,是因为真正的比较结果为1,而错误的结果为0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多