使用 WITH 作为聚合值

Using a WITH as an aggregate value

我正在查询 Presto table,我想在其中计算行的特定子集占总数的百分比。

考虑这样的 table:

id m
1 5
1 7
2 9
3 8

我想查询报告每个 id 贡献了多少总度量 (m)。在此示例中,度量列的总数为 29 我可以使用类似...

的查询找到它吗
SELECT SUM("m") FROM t;

输出:

sqlite> SELECT SUM("m") FROM t;
29

然后我想按 id 对某些 id 进行小计,例如

SELECT "id", SUM("m") AS "sub_total" FROM t WHERE "id" IN ('1','3') GROUP BY id;

输出:

sqlite> SELECT "id", SUM("m") AS "sub_total" FROM t WHERE "id" IN ('1','3') GROUP BY id;
1|12
3|8

现在我想添加第三列,其中小计除以总计 (29) 以获得每个选定 ID 的百分比。

我试过了:

sqlite>
WITH a AS (
 SELECT SUM("m") AS g FROM t )
SELECT "id", SUM("m") AS "sub_total", SUM(m)*100/"a"."g"
FROM a, t
  WHERE "t"."id" IN ('1','3') GROUP BY "t"."id";

输出:

1|12|41
3|8|27

在 SQLLite3 中这一切都很好!但是当我将其转换为我的实际 Presto DB(以及正确的 table 和列)时,我收到此错误:

presto error: line 10:5: 'a.g' must be an aggregate expression or appear in GROUP BY clause

我不明白我在这里遗漏了什么或者为什么这在 Presto 中会有所不同。

当您的查询中有 GROUP BY 时,查询中的所有表达式 returning 必须是:

  • 您分组的表达式
  • 或聚合函数

例如,如果您执行 GROUP BY id,结果查询将 return 每个 id 一行 - 您不能只使用 m,因为 id = 1 有两个值:57 - 那么应该 returned 什么?第一个值,最后一个,总和,平均值?您需要使用 sum(m).

之类的聚合函数来告诉它

a.g 相同 - 您需要将其添加到 GROUP BY

WITH a AS (
 SELECT SUM("m") AS g FROM t )
SELECT "id", SUM("m") AS "sub_total", SUM(m)*100/"a"."g"
FROM a, t
  WHERE "t"."id" IN ('1','3') GROUP BY "t"."id", "a"."g";

PrestoDB 没有什么特别之处,更多的是 SQLite 不那么严格,实际上大多数其他数据库引擎都会抱怨你的情况。