我有以下内容,它为我提供了任何商店位置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米范围内的客户数量,还返回以下内容。 ......内的客户数量。
......任何地点。
我可以通过几种方式开展这项工作。对于给定的客户,只计算一次(到任何商店的最短距离),这将计算每个人一次。我意识到这可能非常复杂。我也愿意多次计算人数,这无论如何都是准确的值,并且认为应该更加简单。
感谢任何指示。
答案 0 :(得分:1)
您可以相对轻松地执行这两种类型的查询。但这里的一个问题是,您不知道哪些客户与哪些商店位置相关联,这似乎是一件有趣的事情。如果需要,请在查询中使用store_name
的PK和locations_table
。请参阅下面的位置ID和store_name的选项。要强调两个选项之间的区别:
这是O(n x m)
正在运行的订单的查询(在CROSS JOIN
和customer_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 JOIN
和customer_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;