【问题标题】:MySQL sort by average of two averagesMySQL按两个平均值的平均值排序
【发布时间】:2010-02-11 22:25:33
【问题描述】:

我在一个竞赛网站上工作,该网站有两种类型的用户,普通网站成员和评委。每个人都可以使用拖放工具按照他们选择的顺序对特定比赛中的参赛作品进行排序。完成后,相关条目 ID 会附加一个排名值,然后可用于确定比赛中哪个条目获得最高平均分。获胜者实际上将通过平均每组的平均值来确定。

我希望最终得到一个表格,显示特定比赛中的每个条目,带有标题,然后显示 3 个值,该条目的 avg_normal,该条目的 avg_judge,然后将这两个值加在一起,除以二,所以 avg_normal 和 avg_judge 各占 avg_all 的 50%。最后,按 avg_all 对表进行排序。

avg_all = ((avg_normal + avg_judge) / 2)

他们按顺序排列 entry_ids 1、2、3、4、5。排名值从零开始,所以:

entry_id, entry_ranking, author_id
1, 0, 1
2, 1, 1
3, 2, 1
4, 3, 1
5, 4, 1

我希望在 1-100 的范围内确定平均值,因此进入排名为 0 = 100 分、1 = 90、2 = 80、3 = 70,以及任何高于 4 = 5 分的分数

每个用户都附加到另一个表中的组,因此他们要么是普通用户,要么是法官

我希望能够编写一个找到的查询

1.) 普通用户的平均投票分数

2.) JUDGE 用户平均投票分数

3.) NORMAL & JUDGE SCORE 的平均值。

所以普通用户平均 = 93.3333,裁判平均 = 70,总平均 = 81.66665

感谢下面的答案,这两个查询都像冠军一样工作。

【问题讨论】:

    标签: sql mysql sorting average


    【解决方案1】:

    请注意以下几点:

    • 我假设成员中有一个字段 user_type 存储“NORMAL”或“JUDGE”

    • 我已经删除了 title.title 的数据连接和分组依据,因为我看不出它们与您的平均值有什么关系。

    .

    SELECT
      t.title,
      AVG(CASE WHEN user_type = 'NORMAL' THEN IF (r.ranking_value = '0', 100, 0) + IF (r.ranking_value = '1', 90, 0) + IF (r.ranking_value = '2', 80, 0) + IF (r.ranking_value = '3', 70, 0) + IF (r.ranking_value = '4', 5, 0) END) AS avg_normal,
      AVG(CASE WHEN user_type = 'JUDGE' THEN IF (r.ranking_value = '0', 100, 0) + IF (r.ranking_value = '1', 90, 0) + IF (r.ranking_value = '2', 80, 0) + IF (r.ranking_value = '3', 70, 0) + IF (r.ranking_value = '4', 5, 0) END) AS avg_judge,
      (AVG(CASE WHEN user_type = 'NORMAL' THEN IF (r.ranking_value = '0', 100, 0) + IF (r.ranking_value = '1', 90, 0) + IF (r.ranking_value = '2', 80, 0) + IF (r.ranking_value = '3', 70, 0) + IF (r.ranking_value = '4', 5, 0) END) +
      AVG(CASE WHEN user_type = 'JUDGE' THEN IF (r.ranking_value = '0', 100, 0) + IF (r.ranking_value = '1', 90, 0) + IF (r.ranking_value = '2', 80, 0) + IF (r.ranking_value = '3', 70, 0) + IF (r.ranking_value = '4', 5, 0) END)) / 2 AS avg_all
    FROM rankings r
    LEFT JOIN titles t
      ON r.entry_id = t.entry_id
    LEFT JOIN members m
      ON t.author_id = m.member_id
    WHERE r.contest_id IN ('CONTEST ID NUMBER')
    GROUP BY
      t.title
    ORDER BY
      avg_all;
    

    【讨论】:

    • 在这里感谢您的帮助,这绝对是更近了一步。我不知道我是否完全清楚。我希望做的是最终得到一个表格,显示特定比赛中的每个条目,带有标题,然后显示 3 个值,该条目的 avg_normal,该条目的 avg_judge,然后将这两个值相加并除以二,所以avg_normal和avg_normal各占avg_all的50%。最后,按 avg_all 对表进行排序。 avg_all = ((avg_normal + avg_judge) / 2) 这样更清楚吗?非常感谢您提供的任何见解
    • 更新了查询。希望这是你想要的。
    • 似乎更接近,但我收到以下错误:(#1054 - '字段列表'中的未知列'avg_normal')。我用适当的值将我的最新查询粘贴到原始问题中
    • 已更新,希望现在可以使用。问题可能是不能引用别名列,所以我所做的是为 avg_normal 和 avg_judge 复制相同的代码。一种不那么混乱的方法是像 roobaron 所做的那样将另一个选择包裹在它周围(尽管 ORDER BY 仍然需要在外面)。
    • 太棒了,效果很好,谢谢你花时间为我做这个,我真的很感激
    【解决方案2】:

    所有这些更改都包含原始查询,lines314159 有大部分工作

    选择 aa.title,aa.avg_normal,aa.avg_judge,(aa.avg_normal + aa.avg_judge) / 2 AS avg_all 从 ( 选择 t.title, AVG(CASE WHEN group_id = '6' THEN IF (r.ranking_value = '0', 100, 0) + IF (r.ranking_value = '1', 90, 0) + IF (r.ranking_value = '2', 80, 0) + IF (r.ranking_value = '3', 70, 0) + IF (r.ranking_value >= '4', 5, 0) END) AS avg_normal, AVG(CASE WHEN group_id = '7' THEN IF (r.ranking_value = '0', 100, 0) + IF (r.ranking_value = '1', 90, 0) + IF (r.ranking_value = '2', 80, 0) + IF (r.ranking_value = '3', 70, 0) + IF (r.ranking_value >= '4', 5, 0) END) AS avg_judge FROM exp_rankings r 左连接 exp_weblog_titles t ON r.entry_id = t.entry_id 左加入 exp_members m ON t.author_id = m.member_id WHERE r.contest_id IN ('22') 通过...分组 t.title 订购方式 avg_all) 作为aa;

    【讨论】:

    • 这是 99%,我想我遇到了等号 = 符号的语法问题(CASE WHEN group_id = '7' THEN IF)。作为测试,如果我将其更改为 != 它可以工作并为我提供其他值,但按原样,它只返回 NULLs
    • 知道了,其中一个连接有点不对劲,我的错,(LEFT JOIN exp_members m ON t.author_id = m.member_id) 应该是 (LEFT JOIN exp_members m ON r.author_id = m 。会员ID)。谢谢你
    猜你喜欢
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    相关资源
    最近更新 更多