从函数中返回多列的SELECT

时间:2019-02-25 14:05:49

标签: postgresql postgis

我有以下查询,它对位置进行聚类,并返回一个聚类ID,以及一个包含该聚类中原始点的结构:

SELECT
    cluster_id,
    ST_AsGeoJSON(ST_Collect(origin)) AS points
FROM (
    SELECT
        origin,
        ST_ClusterDBSCAN(origin, eps := 0.01, minPoints := 5) OVER(ORDER BY id) AS cluster_id
    FROM
        ride
    WHERE
        region_id = 1 AND
        created_at > now() - interval '1 week'
) a
WHERE cluster_id IS NOT NULL
GROUP BY cluster_id

示例输出:

3   {"type":"MultiPoint","coordinates":[ ... ]}
4   {"type":"MultiPoint","coordinates":[ ... ]}

我不想返回原始点,而是要返回聚类的边界圆(中心和半径),可以使用ST_MinimumBoundingRadius完成此操作:

SELECT
    ST_AsGeoJSON(center),
    radius
FROM
    ST_MinimumBoundingRadius(
        ST_GeomFromGeoJSON('{"type":"MultiPoint","coordinates":[ ... ]}')
    )

示例输出:

{"type":"Point","coordinates":[ ... ]}  0.002677744742706528

但是,由于ST_MinimumBoundingRadius返回两列,因此以下内容会引发错误:

SELECT
    cluster_id,
    ST_MinimumBoundingRadius(ST_Collect(origin))
FROM (
    ...
) a
WHERE cluster_id IS NOT NULL
GROUP BY cluster_id;

我发现了this个问题,其中提到使用LATERAL,但是我无法获得有效的查询。

正确的方法是什么?

2 个答案:

答案 0 :(得分:2)

尝试另一个子选择:

SELECT q.cluster_id,
       (q.mbr).radius,
       (q.mbr).center
FROM (
   SELECT cluster_id,
          ST_MinimumBoundingRadius(
             ST_Collect(origin)
          ) AS mbr
   FROM (
      ...
   ) AS a
) AS q;

答案 1 :(得分:0)

最后真的很简单,不知道我怎么没想到这一点。

SELECT
    cluster_id,
    (ST_MinimumBoundingRadius(ST_Collect(origin))).*
FROM (
    SELECT
        origin,
        ST_ClusterDBSCAN(origin, eps := 0.01, minPoints := 5) OVER(ORDER BY id) AS cluster_id
    FROM
        ride
    WHERE
        region_id = 1 AND
        created_at > now() - interval '1 week'
) a
WHERE cluster_id IS NOT NULL
GROUP BY cluster_id