从另一组点计算一定距离范围内的点数
Count number of points within certain distance ranges from another set of points
我有以下信息,它给出了任何商店位置 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
)
我需要的是这个查询要return不仅要查询10000米以内的客户数,还要查询以下。客户数量...
- 10,000 米
- 超过10,000,但少于50,000
- 超过 50,000,但少于 10,0000
- 超过 100,000
...任何位置。
我对这种工作方式持开放态度。对于给定的顾客,只计算他们一次(到任何商店的最短距离),这会将每个人都计算一次。我意识到这可能非常复杂。我也愿意让人们被多次计算,无论如何这确实是准确的值并且认为应该更简单。
感谢任何指导。
您可以相对轻松地进行这两种类型的查询。但这里的一个问题是您不知道哪些客户与哪些商店位置相关联,这似乎是一件有趣的事情。如果需要,请在查询中使用 locations_table
的 PK 和 store_name
。请参阅下面带有位置 ID 和 store_name 的两个选项。强调两个选项的区别:
- 第一个选项表示每个商店位置的每个距离 class 有多少顾客,每个商店位置的所有顾客。
- 第二个选项表示每个商店位置的每个距离 class 中有多少顾客,仅限 每个顾客最近的商店位置。
这是一个 O(n x m)
运行 顺序的查询(使用 customer_table
和 locations_table
之间的 CROSS JOIN
实现)并且可能会变得相当慢在 table.
中增加行数
计算所有距离的客户数量 classes
您应该 CROSS JOIN
计算客户与商店位置的距离,然后按商店位置 ID、名称和您定义的最大距离 class 对它们进行分组。您可以使用 VALUES
命令从距离 classes 创建一个 "table",然后您可以在任何查询中简单地使用它:
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;
数最近距离内的顾客数class
如果您只想在最近的距离 class 中列出客户,那么您应该在 customer_table
和 locations_table
上制作与前一种情况相同的 CROSS JOIN
,但是然后简单地 select 最低组(即最近的商店)使用查询中的 CASE
子句和 GROUP BY
存储位置 id、名称和距离 class 和以前一样:
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;
我有以下信息,它给出了任何商店位置 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
)
我需要的是这个查询要return不仅要查询10000米以内的客户数,还要查询以下。客户数量...
- 10,000 米
- 超过10,000,但少于50,000
- 超过 50,000,但少于 10,0000
- 超过 100,000
...任何位置。
我对这种工作方式持开放态度。对于给定的顾客,只计算他们一次(到任何商店的最短距离),这会将每个人都计算一次。我意识到这可能非常复杂。我也愿意让人们被多次计算,无论如何这确实是准确的值并且认为应该更简单。
感谢任何指导。
您可以相对轻松地进行这两种类型的查询。但这里的一个问题是您不知道哪些客户与哪些商店位置相关联,这似乎是一件有趣的事情。如果需要,请在查询中使用 locations_table
的 PK 和 store_name
。请参阅下面带有位置 ID 和 store_name 的两个选项。强调两个选项的区别:
- 第一个选项表示每个商店位置的每个距离 class 有多少顾客,每个商店位置的所有顾客。
- 第二个选项表示每个商店位置的每个距离 class 中有多少顾客,仅限 每个顾客最近的商店位置。
这是一个 O(n x m)
运行 顺序的查询(使用 customer_table
和 locations_table
之间的 CROSS JOIN
实现)并且可能会变得相当慢在 table.
计算所有距离的客户数量 classes
您应该 CROSS JOIN
计算客户与商店位置的距离,然后按商店位置 ID、名称和您定义的最大距离 class 对它们进行分组。您可以使用 VALUES
命令从距离 classes 创建一个 "table",然后您可以在任何查询中简单地使用它:
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;
数最近距离内的顾客数class
如果您只想在最近的距离 class 中列出客户,那么您应该在 customer_table
和 locations_table
上制作与前一种情况相同的 CROSS JOIN
,但是然后简单地 select 最低组(即最近的商店)使用查询中的 CASE
子句和 GROUP BY
存储位置 id、名称和距离 class 和以前一样:
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;