计算距离另一组点的特定距离范围内的点数

时间:2015-05-11 23:08:51

标签: postgresql postgis

我有以下内容,它为我提供了任何商店位置10,000米范围内的客户数量:

SELECT COUNT(*) as customer_count FROM customer_table c
WHERE EXISTS(
SELECT 1 FROM locations_table s
WHERE ST_Distance_Sphere(s.the_geom, c.the_geom) < 10000
)

我需要的是此查询不仅返回10,000米范围内的客户数量,还返回以下内容。 ......内的客户数量。

  1. 10,000米
  2. 超过10,000,但少于50,000
  3. 超过50,000,但不到10,0000
  4. 超过100,000
  5. ......任何地点。

    我可以通过几种方式开展这项工作。对于给定的客户,只计算一次(到任何商店的最短距离),这将计算每个人一次。我意识到这可能非常复杂。我也愿意多次计算人数,这无论如何都是准确的值,并且认为应该更加简单。

    感谢任何指示。

1 个答案:

答案 0 :(得分:1)

您可以相对轻松地执行这两种类型的查询。但这里的一个问题是,您不知道哪些客户与哪些商店位置相关联,这似乎是一件有趣的事情。如果需要,请在查询中使用store_name的PK和locations_table。请参阅下面的位置ID和store_name的选项。要强调两个选项之间的区别:

  • 第一个选项表示每个商店位置的每个距离类别中有多少客户,每个商店位置的所有客户
  • 第二个选项表示每个商店位置的每个距离等级中有多少客户,仅限每个客户的最近的商店位置

这是O(n x m)正在运行的订单的查询(在CROSS JOINcustomer_table之间使用locations_table实施),并且随着行数增加而变得相当慢表

计算所有距离类别的客户

您应该在客户距商店位置的距离之间设置CROSS JOIN,然后按商店位置ID,名称和您定义的最大距离类别对它们进行分组。您可以使用VALUES命令从距离类创建“表格”,然后您可以在任何查询中使用该表:

SELECT loc_dist.id, loc_dist.store_name, grps.grp, count(*)
FROM (
    SELECT s.id, s.store_name, ST_Distance_Sphere(s.the_geom, c.the_geom) AS dist
    FROM customer_table c, locations_table s) AS loc_dist
JOIN (
    VALUES(1, 10000.), (2, 50000.), (3, 100000.), (4, 1000000.)
  ) AS grps(grp, dist) ON loc_dist.dist < grps.dist
GROUP BY 1, 2, 3
ORDER BY 1, 2, 3;

以最近的距离等级计算客户

如果您希望客户仅列在最近的距离类别中,那么您应该像前一种情况一样在CROSS JOINcustomer_table上制作相同的locations_table,但只需选择最低的使用查询中的CASE子句和GROUP BY存储位置ID,名称和距离类的组(即最近的商店):

SELECT 
  id, store_name,
  CASE
    WHEN dist <  10000. THEN 1
    WHEN dist <  50000. THEN 2
    WHEN dist < 100000. THEN 3
    ELSE 4
  END AS grp,
  count(*)
FROM (
    SELECT s.id, s.store_name, ST_Distance_Sphere(s.the_geom, c.the_geom) AS dist
    FROM customer_table c, locations_table s) AS loc_dist
GROUP BY 1, 2, 3
ORDER BY 1, 2, 3;