我正在使用PostgreSQL学习SQL,并且遇到了有关嵌套聚合函数的问题。
我正在尝试查找具有最大数量属性的私人所有者的详细信息,其中我有两个关系,privateowner和propertyforrent以及具有外键的propertyforrent,ownwerno。
我怀疑我的问题是我试图嵌套聚合函数的地方,但我找不到解决方法。
注意: - 我正在使用的数据库在propertyforrent的属性ownwerno中有一个拼写错误,它应该是ownerno。
我试图使用的代码如下所示〜: -
SELECT o.fname, o.lname, telno
FROM privateowner o
WHERE o.ownerno = (SELECT p.ownwerno
FROM propertyforrent p
HAVING COUNT(p.ownwerno) = MAX(COUNT(o.ownerno)));
其伴随的错误如下: -
ERROR: column "p.ownwerno" must appear in the GROUP BY clause or be used in a
aggregate function
LINE 3: WHERE o.ownerno = (SELECT p.ownwerno
^
********** Error **********
ERROR: column "p.ownwerno" must appear in the GROUP BY clause or be used in an
aggregate function
SQL state: 42803
Character: 78
任何见解都会很棒。
答案 0 :(得分:5)
PostgreSQL 9.1架构设置:
create table privateowner(ownerno integer, fname text);
insert into privateowner(ownerno, fname) values (1,'Alice'),
(2,'Bob'),
(3,'Charlie');
create table propertyforrent(ownerno integer);
insert into propertyforrent(ownerno) values (1), (2), (2), (3), (3);
查询1 :
with w as ( select ownerno, count(*) as property_count
from propertyforrent
group by ownerno )
select *
from privateowner
where ownerno in( select ownerno
from w
where property_count=( select property_count
from w
order by 1 desc limit 1) )
<强>结果:
| OWNERNO | FNAME |
---------------------
| 2 | Bob |
| 3 | Charlie |
请参阅此on SQL Fiddle
受@ araqnid的回答(+1)的启发,这是另一个带窗口函数的变体:
<强>查询强>:
select ownerno, fname
from( select ownerno, fname, rank() over (order by count(*) desc) rnk
from privateowner join propertyforrent using(ownerno)
group by ownerno, fname ) z
where rnk=1
<强>结果:
| OWNERNO | FNAME |
---------------------
| 3 | Charlie |
| 2 | Bob |
请参阅此on SQL Fiddle
答案 1 :(得分:2)
问题在于您无法嵌套聚合函数。
您想要的更像是以下内容:
SELECT o.fname, o.lname, telno
FROM privateowner o
WHERE o.ownerno = (SELECT p.ownwerno
FROM propertyforrent p
GROUP BY p.owerno
order by COUNT(*)
limit 1
)
但是,我更喜欢使用显式连接的查询:
select o.fname, ollname, o.telno, numProperties
from PrivateOwner o join
(select p.ownerno, count(*) as numProperties
from PropertyForRent pft
group by p.owerno
) pfr
on o.ownerno = pfr.ownerno
order by NumProperties
limit 1
使用联接,您还可以添加属性数。而且,您也可以选择多个。要获得具有最大值的所有属性,可以使用以下where
子句:
where NumProperties = (select count(*) as NumProperties
from PropertyForRent
group by owerno
order by 1 desc
limit 1
)
答案 2 :(得分:2)
这是窗口函数运行良好的情况,尽管如果您刚开始使用SQL,您可能希望在您更熟悉基础知识时再回过头来看。
select ownerno, fname
from (
select privateowner.*, rank() over(order by property_count desc)
from privateowner join (
select ownerno, count(*) as property_count
from propertyforrent group by ownerno
) owner_stats using (ownerno)
) x
where x.rank = 1