如何显示额外的列而不是聚合函数或不在 group by 语句中

发布于 2024-12-20 15:19:25 字数 329 浏览 1 评论 0原文

我正在使用 postgis 来计算每个“a”与其相应的“b”类型点之间的距离。

到目前为止,我已经设法用这个查询来做到这一点:

SELECT a.name, min(ST_Distance(a.the_geom, b.the_geom)) as distance
FROM a, b
GROUP BY a.name;

这是有效的,但是它只列出了 a 类型点的名称以及到它最近的 b 类型点的距离,它没有列出最近的 b 类型点的名称每个都是我想要的类型点。

我通常会通过连接两个表来做到这一点,但它们不相关并且不共享键,所以我不知道如何连接它们。

I am using postgis to calculate the distance between every 'a' and its corresponding 'b' type point.

So far I have managed to do this with this query:

SELECT a.name, min(ST_Distance(a.the_geom, b.the_geom)) as distance
FROM a, b
GROUP BY a.name;

This works, it however only lists the name of the a type point and the distance to its closest b type point, it doesn't list the name of the closest b type point to each a type point as I'd like it to do.

I would usually do this by joining both tables but they are unrelated and share no keys so I wouldn't know how to join them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦途 2024-12-27 15:19:25

暴力方法(假设PostGIS支持WITH子句,并假设我的WITH子句语法正确 - 两个未经检查的假设):

WITH (SELECT a.name AS a_name, b.name AS b_name, ST_Distance(a.the_geom, b.the_geom) as distance
        FROM a, b  -- Cartesian product (not efficient!)
     ) AS distances
SELECT d1.a_name, d1.b_name, d1.distance
  FROM distances AS d1
  JOIN (SELECT a_name, MIN(distance) AS distance
          FROM distances
         GROUP BY a_name) AS d2

这会生成名称列表(a_nameb_name) 加上使用笛卡尔积的相应距离(这是您的原始查询在 GROUP BY 启动之前执行的操作)。然后,它选择两个名称以及该表与通过 a_name 分组并在 a_name 上连接的同一表的连接距离以及最小距离。

显然,如果不支持WITH,您可以将WITH 子句写出两次,并希望您的优化器是好的。

The brute force approach (assuming that PostGIS supports WITH clauses, and assuming I have the syntax of WITH clauses correct - both unchecked assumptions):

WITH (SELECT a.name AS a_name, b.name AS b_name, ST_Distance(a.the_geom, b.the_geom) as distance
        FROM a, b  -- Cartesian product (not efficient!)
     ) AS distances
SELECT d1.a_name, d1.b_name, d1.distance
  FROM distances AS d1
  JOIN (SELECT a_name, MIN(distance) AS distance
          FROM distances
         GROUP BY a_name) AS d2

This generates the list of names (a_name and b_name) plus the corresponding distance using a Cartesian product (which is what your original query does before the GROUP BY kicks in). It then selects the two names and the distance from the join of that table with the same table grouped over the a_name and joined on the a_name and the minimum distance.

Clearly, if WITH is not supported, you can write the WITH clause out twice and hope your optimizer is good.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文