来自两个表的MySQL评级

时间:2010-03-26 17:48:49

标签: mysql

我正在使用MySQL和PHP为Flash游戏构建数据层。检索关卡列表非常简单,但是我试图获取关卡的平均评级及其指针信息时遇到了障碍。以下是一个示例数据集:

级别表:

level_id | level_name
       1 | Some Level
       2 | Second Level
       3 | Third Level

评级表:

rating_id | level_id | rating_value
        1 |    1     |      3
        2 |    1     |      4
        3 |    1     |      1
        4 |    2     |      3
        5 |    2     |      4
        6 |    2     |      1
        7 |    3     |      3
        8 |    3     |      4
        9 |    3     |      1

我知道这需要一个连接,但是当我请求一个级别列表时,我无法弄清楚如何根据level_id获得平均评级值。这就是我想要做的事情:

SELECT levels.level_id, AVG(ratings.level_rating WHERE levels.level_id = ratings.level_id) FROM levels

我知道我的SQL存在缺陷,但我无法弄清楚如何将这个概念贯穿其中。我唯一可以工作的是从整个评级表中返回一个平均值,这不是很有用。

理想输出来自上述概念上有效但语法错误的查询将是:

level_id | level_rating
        1| 3.34
        2| 1.00
        3| 4.54 

我的主要问题是我无法弄清楚如何在返回查询之前使用每个响应行的level_id。这就像我想要使用占位符......或别名......我真的不知道,这非常令人沮丧。我现在的解决方案是EPIC创可贴,只会让我长期遇到问题......请帮忙!

3 个答案:

答案 0 :(得分:2)

如果您的levels表格为InnoDB

SELECT  l.level_id, COALESCE(AVG(level_rating), 0)
FROM    levels l
LEFT JOIN
        ratings r
GROUP BY
        l.id

如果您的levels表格为MyISAM

SELECT  l.level_id,
        (
        SELECT  COALESCE(AVG(level_rating), 0)
        FROM    rating r
        WHERE   r.level_id = l.level_id
        )
FROM    levels l

子查询对MyISAM更有效,因为它是基于堆的,GROUP BY需要排序和/或实现。

答案 1 :(得分:1)

您需要添加GROUP BY子句。试试这个:

SELECT   levels.level_id
       , AVG(ratings.level_rating)
FROM     levels
JOIN     ratings ON levels.level_id = ratings.level_id
GROUP BY levels.level_id

使用聚合函数(AVG,SUM,COUNT,MIN,MAX)时,需要按照所选的其他属性对查询进行分组。这就是为什么SELECT AVG(ratings.level_rating)在没有GROUP BY的情况下工作的原因,但尝试选择level_id也需要分组。

答案 2 :(得分:1)

尝试一下:

SELECT level_id, AVG(ratings.level_rating)
FROM levels JOIN ratings USING(level_id)
GROUP BY level_id

请注意,level_id永远不会引用特定的表,因为它在联接的USING部分中使用