Had*_*adi 33 sql postgresql group-by having
我在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;
Run Code Online (Sandbox Code Playgroud)
为什么我会收到此错误:
错误:列"overall_count"不存在
我的表结构:
License(license_id, license_name, limit_call, create_date, expire_date)
Log(log_id, license_id, log, call_date)
Run Code Online (Sandbox Code Playgroud)
我想检查许可证是否已达到特定月份的通话限制.
Erw*_*ter 47
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)
Run Code Online (Sandbox Code Playgroud)
在PostgreSQL 9.1之前的版本中,您必须添加limit_call到该GROUP BY子句中.从版本9.1开始,在GROUP BY子句中使用主键就足够了.9.1的发行说明:
GROUP BY在GROUP BY子句中指定主键时,允许查询目标列表中的非列
您的WHERE条件必须移动到HAVING子句,因为它引用了聚合函数的结果.并且您不能在子句中引用输出列(列别名)HAVING,其中您只能引用输入列.所以你必须重复表达.每个文件:
输出列的名称可用于引用列的值in
ORDER BY和GROUP BY子句,但不能用于WHERE或HAVING子句; 那里你必须写出表达式.
我颠倒了FROM子句中表的顺序,并稍微清理了语法,使其不那么混乱.USING这里只是一个标志性的便利.
我使用的是LEFT JOIN代替JOIN,因此您根本不排除没有任何日志的许可证.
如果可能的话,我建议不要在Postgres中使用混合大小写标识符.非常容易出错.
只计算非空值count().由于您想要计算表中的相关条目,"Log"因此使用起来更安全且更便宜count(b.license_id).此列用于连接,因此我们无需担心列是否为null.
count(*)更短,更快,但更快.如果您不介意在左表中1获取0行数,请使用它.
epo*_*pox 21
SELECT COUNT(*) FILTER(where a.myfield > 0) AS my_count
FROM "Log" as a
GROUP BY a.license_id
Run Code Online (Sandbox Code Playgroud)
那么你:
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)
Run Code Online (Sandbox Code Playgroud)
并且不关心COUNT(a.log_id)第一行和最后一行中的重复表达式。Postgres 会对其进行优化。
小智 6
该where查询不认识你列的别名,而且,你要过滤掉行后聚集.尝试:
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);
Run Code Online (Sandbox Code Playgroud)
该having子句类似于该where子句,除了它处理聚合后的列,而该where子句在聚合之前处理列.
另外,您的表名是否用双引号括起来?
| 归档时间: |
|
| 查看次数: |
36150 次 |
| 最近记录: |