【问题标题】:SELECT from function which returns multiple columns从返回多列的函数中选择
【发布时间】:2019-02-25 14:05:49
【问题描述】:

我有以下查询,它对位置进行聚类,并返回一个聚类 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,但我无法获得有效的查询。

这样做的正确方法是什么?

【问题讨论】:

    标签: postgresql postgis


    【解决方案1】:

    尝试另一个子选择:

    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;
    

    【讨论】:

      【解决方案2】:

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

      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
      

      【讨论】:

      • 这将最终调用该函数两次。如果您想避免这种情况,请使用另一个选择 centerradius 属性的外部查询来包装查询。
      • (SELECT center, radius FROM ST_MinimumBoundingRadius(bounds)).*?这会引发我之前遇到的相同错误 - ERROR: subquery must return only one column
      • 我的意思是SELECT x.center, x.radius FROM (SELECT st_minimumboundingradius(...) AS x FROM ...) AS q
      • 您能发表您的建议作为答案吗?我已经尝试过你的建议,但得到ERROR: missing FROM-clause entry for table "x"
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多