SQL聚合函数嵌套

时间:2012-11-30 15:02:49

标签: sql postgresql aggregate

我正在使用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

任何见解都会很棒。

3 个答案:

答案 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