0

Postgres 9.3.5、PostGIS 2.1.4。

データベースに 2 つのテーブル (polygonspoints) があります。

pointsそれぞれ何個入っているか知りたいですpolygon。ポリゴンあたり 0 ポイントまたは 200000 以上になります。

pointのテーブルは次のようになります。

x    y    lan
10  11    en
10  11    fr
10  11    en
10  11    es
10  11    en
- #just for demonstration/clarification purposes
13  14    fr
13  14    fr
13  14    es
-
15  16    ar
15  16    ar
15  16    ps

ポリゴンごとのポイント数を単純に数えたいわけではありません。lan各ポリゴンで最も頻繁に発生するものを知りたいです。-したがって、それぞれがポイントが新しいポリゴンに分類されていることを示していると仮定すると、結果は次のようになります。

Polygonテーブル:

polygon    Count   lan
1          3       en
2          2       fr
3          2       ar

これは私がこれまでに得たものです。

SELECT count(*), count.language AS language, hexagons.gid AS hexagonsWhere 
  FROM hexagonslan AS hexagons, 
       points_count AS france 
 WHERE ST_Within(count.geom, hexagons.geom) 
 GROUP BY language, hexagonsWhere 
 ORDER BY hexagons DESC;

それは私に次のことを与えます:

Polygon    Count     language
1          3         en
1          1         fr
1          1         es
2          2         fr
2          1         es
3          2         ar
3          1         ps

不明な点が 2 つあります。

  1. 最大値のみを取得するには?
  2. 万一最大値が同じである場合はどのように扱われますか?
4

1 に答える 1

1

1に答えてください。

Polygon ごとの最も一般的な言語とその数を取得するには、単純なDISTINCT ONクエリを使用できます。

SELECT DISTINCT ON (h.gid)
       h.gid AS polygon, count(c.geom) AS ct, c.language
FROM   hexagonslan h
LEFT   JOIN points_count c ON ST_Within(c.geom, h.geom)
GROUP  BY h.gid, c.language
ORDER  BY h.gid, count(c.geom) DESC, c.language;  -- language name is tiebreaker

ただし、説明したデータ分布 (ポリゴンあたり最大 200.000 ポイント) の場合、これはかなり高速になるはずです(上のインデックスをより有効に活用することを期待していますc.geom)。

SELECT h.gid AS polygon, c.ct, c.language
FROM   hexagonslan h
LEFT   JOIN LATERAL (
   SELECT c.language, count(*) AS ct
   FROM   points_count c
   WHERE  ST_Within(c.geom, h.geom) 
   GROUP  BY 1
   ORDER  BY 2 DESC, 1  -- again, language name is tiebreaker
   LIMIT  1
   ) c ON true
ORDER  BY 1;

LEFT JOIN LATERAL .. ON trueポイントを含まないポリゴンを保持します。

の例ではcases where there are by any chance the max values identical、追加された項目によって、アルファベット順で最初の言語が選択されていORDER BYます。すべての言語でたまたま最大数を共有したい場合は、さらに多くのことを行う必要があります。

2に答えてください。

SELECT h.gid AS polygon, c.ct, c.language
FROM   hexagonslan h
LEFT   JOIN LATERAL (
   SELECT c.language, count(*) AS ct
        , rank() OVER (ORDER BY count(*) DESC) AS rnk
   FROM   points_count c
   WHERE  ST_Within(c.geom, h.geom) 
   GROUP  BY 1
   ) c ON c.rnk = 1
ORDER  BY 1, 3  -- language only as additional sort critieria

ここでウィンドウ関数rank()を使用します (違いrow_number()ます!)。カウントまたはポイントカウントのランキングを 1 つの で取得できますSELECT。イベントのシーケンスを検討してください。

于 2015-05-30T00:23:03.827 に答える