我在 PostgreSQL 中有以下查询:
SELECT
COUNT(a.log_id) AS overall_count
FROM
"Log" as a,
"License" as b
WHERE
a.license_id=7
AND
a.license_id=b.license_id
AND
b.limit_call > overall_count
GROUP BY
a.license_id;
为什么会出现此错误:
错误:列“overall_count”不存在
我的表结构:
License(license_id, license_name, limit_call, create_date, expire_date)
Log(log_id, license_id, log, call_date)
我想检查许可证是否已达到特定月份的调用限制。
SELECT a.license_id, a.limit_call
, count(b.license_id) AS overall_count
FROM "License" a
LEFT JOIN "Log" b USING (license_id)
WHERE a.license_id = 7
GROUP BY a.license_id -- , a.limit_call -- add in old versions
HAVING a.limit_call > count(b.license_id)
自 Postgres 9.1 以来,主键涵盖了
GROUP BY
子句中表的所有列。在旧版本中,您必须将 a.limit_call
添加到 GROUP BY
列表中。 9.1的发行说明:
允许非
列在查询目标列表中,当主 key 在GROUP BY
子句中指定GROUP BY
延伸阅读:
您在
WHERE
子句中的条件必须移动到 HAVING
子句,因为它指的是聚合函数的结果(after WHERE
已应用)。并且您不能在 HAVING
子句中引用 output columns(列别名),您只能在其中引用输入列。所以你必须重复这个表达。 说明书:
输出列的名称可用于引用列中的值
和ORDER BY
从句,但不在GROUP BY
或WHERE
条款;在那里你必须写出表达式。HAVING
我颠倒了
FROM
子句中的表格顺序,并稍微清理了语法以减少混淆。 USING
在这里只是为了方便记号。
我使用了
LEFT JOIN
而不是JOIN
,所以你根本不会排除没有任何日志的许可证。
count()
只计算非空值。由于您想在表"Log"
中计算相关条目,因此使用
count(b.license_id)
更安全且稍微便宜一些。这个列在连接中使用,所以我们不必担心列是否可以为空。count(*)
更短,速度稍快。如果您不介意为左表中的1
行计算0
的数量,请使用它。
旁白:如果可能的话,我会建议not在Postgres中使用混合大小写标识符。非常容易出错。
SELECT COUNT(*) FILTER(where a.myfield > 0) AS my_count
FROM "Log" as a
GROUP BY a.license_id
所以你:
0
对于条件永远不满足的组注意:您不能使用
HAVING b.limit_call > ...
,除非您按limit_call
分组。但是您可以使用聚合函数将组中的许多“limit_calls”映射为单个值。例如,在您的情况下,您可以使用 MAX
:
SELECT COUNT(a.log_id) AS overall_count
FROM "Log" as a
JOIN "License" b ON(a.license_id=b.license_id)
GROUP BY a.license_id
HAVING MAX(b.limit_call) > COUNT(a.log_id)
并且不要在意在第一行和最后一行中重复
COUNT(a.log_id)
表达式。 Postgres 会优化它。
where
查询无法识别您的列别名,此外,您正在尝试过滤掉after 聚合的行。尝试:
SELECT
COUNT(a.log_id) AS overall_count
FROM
"Log" as a,
"License" as b
WHERE
a.license_id=7
AND
a.license_id=b.license_id
GROUP BY
a.license_id
having b.limit_call > count(a.log_id);
having
子句类似于 where
子句,除了它在聚合之后处理列,而 where
子句在聚合之前处理列。
还有,你的表名用双引号括起来是不是有原因?