SQL:以 AVG() 作为条件但未给出正确输出的情况
SQL: CASE WHEN having AVG() as condition not giving right output
我有 table 个唯一用户,每个用户都有一个“评分”列(这是他们在不同 table 评论中给出的所有评分中给出的平均评分)。我想在我的 table 中添加另一列,它指定他们给出的评分高于所有用户的所有评分的平均值(因此我使用 AVG() 函数),低于或平均(我调用它“偏见”)。换句话说,我想看看每个用户给出的平均评分是高于还是低于总平均评分。我理解这个查询的局限性,理想情况下我会包括一个间隔(即低于或高于平均值 0.5 分以内仍算作平均值)但我似乎无法进行最简单的查询。
我一直在使用来自 Coursera 课程的 Yelp 数据集,但我试图创建一个样本,它产生了我不想要的相同结果——只有一行。我想对每一行进行这种分类,因此在这个例子中它应该 return 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
SELECT id,
rating,
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
部分中指定任何内容时,它将聚合整个 table 从而将其减少为一行。
通常,您 select 聚合列和 non-aggregated 列而不指定 GROUP BY
列表中的非聚合列。我不是允许这种行为的 DBMS 的忠实粉丝(SQLLite 似乎是一个罪犯)。
我在上面的查询中所做的是,我使用子查询计算了整个 table 的平均值。然后将每一行与平均值进行比较。
或者像其他人指定的那样,您可以使用 WINDOW 函数。您在 window 定义的数据的某些部分应用函数的地方。它们看起来像常规的聚合函数对应部分,但您会注意到 OVER
关键字指定它们应用于 window。在 over 子句中,您可以对数据进行分区,也可以将其作为一个整体使用。例如,如果您有多个商店和每个商店每天的销售额,您可以按商店进行分区以计算每个商店的平均值。
你不能像这样使用聚合函数AVG()
。
但是你可以用 AVG()
window 函数来做到:
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 |
我有 table 个唯一用户,每个用户都有一个“评分”列(这是他们在不同 table 评论中给出的所有评分中给出的平均评分)。我想在我的 table 中添加另一列,它指定他们给出的评分高于所有用户的所有评分的平均值(因此我使用 AVG() 函数),低于或平均(我调用它“偏见”)。换句话说,我想看看每个用户给出的平均评分是高于还是低于总平均评分。我理解这个查询的局限性,理想情况下我会包括一个间隔(即低于或高于平均值 0.5 分以内仍算作平均值)但我似乎无法进行最简单的查询。
我一直在使用来自 Coursera 课程的 Yelp 数据集,但我试图创建一个样本,它产生了我不想要的相同结果——只有一行。我想对每一行进行这种分类,因此在这个例子中它应该 return 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
SELECT id,
rating,
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
部分中指定任何内容时,它将聚合整个 table 从而将其减少为一行。
通常,您 select 聚合列和 non-aggregated 列而不指定 GROUP BY
列表中的非聚合列。我不是允许这种行为的 DBMS 的忠实粉丝(SQLLite 似乎是一个罪犯)。
我在上面的查询中所做的是,我使用子查询计算了整个 table 的平均值。然后将每一行与平均值进行比较。
或者像其他人指定的那样,您可以使用 WINDOW 函数。您在 window 定义的数据的某些部分应用函数的地方。它们看起来像常规的聚合函数对应部分,但您会注意到 OVER
关键字指定它们应用于 window。在 over 子句中,您可以对数据进行分区,也可以将其作为一个整体使用。例如,如果您有多个商店和每个商店每天的销售额,您可以按商店进行分区以计算每个商店的平均值。
你不能像这样使用聚合函数AVG()
。
但是你可以用 AVG()
window 函数来做到:
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 |