3

PostgreSQL で SQL を学習していますが、ネストされた集計関数に関する問題に遭遇しました。

最大量のプロパティを持つ私有所有者の詳細を見つけようとしています。ここでは、privateowner と propertyforrent の 2 つの関係があり、propertyforrent が外部キー ownwerno を持っています。

私の問題は、集約関数をネストしようとしているところにあると思われますが、それを回避する方法がわかりません。

注:- 私が使用しているデータベースには、propertyforrent の属性 ownwerno にタイプミスがあります。

私が使用しようとしているコードを以下に示します~:-

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

どんな洞察も素晴らしいでしょう。

4

3 に答える 3

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 |

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 |

SQL Fiddleでこれを参照してください

于 2012-11-30T15:13:34.327 に答える
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
于 2012-11-30T17:29:31.150 に答える
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
                      )
于 2012-11-30T15:13:28.810 に答える