问题描述
我有一个唯一用户表,每个用户都有一个“评分”列(这是他们在不同评论表中给出的所有评分中给出的平均评分)。我想在表中添加另一列,该列指定他们给出的评分高于所有用户的所有评分的平均值(因此我使用AVG()函数),低于或平均(我称其为“偏见” )。换句话说,我想查看每个用户给出的平均评分是否高于总平均值。我了解此查询的局限性,并且理想情况下,我会包含一个间隔(即低于或高于平均值0.5个点内仍算作平均值),但即使是最简单的查询也无法工作。
我一直在使用Coursera课程中的Yelp数据集,但是我尝试创建一个示例,该示例产生的结果与我不希望的相同-仅一行。我想对每一行进行这种分类,因此在此示例中,它应该返回3行,前两行“低于平均水平”,第三行“高于平均水平”。但是,下面的代码仅产生一行。我一直在使用R,这似乎是我使用了错误的语法,但是在网上搜索30分钟后,我找不到解决方案。
我正在工作,并且希望在Coursera中将sqlite语法用作课程的一部分
CREATE TABLE test
(
id integer primary key,rating integer
);
INSERT INTO test
(id,rating)
VALUES
(1,1);
INSERT INTO test
(id,rating)
VALUES
(2,3);
INSERT INTO test
(id,rating)
VALUES
(3,8);
SELECT id,rating,CASE
WHEN rating > AVG(rating) THEN "above average"
WHEN rating < AVG(rating) THEN "below average"
ELSE "no bias"
END AS "bias"
FROM test
解决方法
您不能像这样使用聚合函数AVG()
。
但是您可以使用AVG()
窗口函数来做到这一点:
SELECT id,rating,CASE
WHEN rating > AVG(rating) OVER () THEN "above average"
WHEN rating < AVG(rating) OVER () THEN "below average"
ELSE "no bias"
END AS "bias"
FROM test
请参见demo。
结果:
| id | rating | bias |
| --- | ------ | ------------- |
| 1 | 1 | below average |
| 2 | 3 | below average |
| 3 | 8 | above average |
,
SELECT id,CASE
WHEN rating > (select AVG(rating) from test) THEN "above average"
WHEN rating < (select AVG(rating) from test) THEN "below average"
ELSE "no bias"
END AS "bias"
FROM test
AVG
是一个聚合函数,与GROUP BY
结合使用。
当您在GROUP BY
部分中未指定任何内容时,它将汇总整个表,从而将其减少为一行。
通常,您选择汇总列和非汇总列,而不在GROUP BY
列表中指定非汇总列。我不是允许这种行为的DBMS的忠实拥护者(SQLLite似乎是一个冒犯者)。
我在上面的查询中所做的是我使用子查询计算了整个表的平均值。然后将每一行与平均值进行比较。
或者像其他人指定的那样,您可以使用WINDOW函数。在窗口定义的数据的某些部分上应用函数的位置。它们看起来像常规的聚合函数组件,但是您会注意到OVER
关键字,它们指定将它们应用于窗口。在over子句中,您可以对数据进行分区,也可以将其整体使用。例如,如果您有多个商店并且每个商店每天都有销售量,则可以按商店进行分区以计算每个商店的平均值。