您可以相对轻松地执行这两种类型的查询。但是这里的一个问题是您不知道哪些客户与哪些商店位置相关联,这似乎是一件有趣的事情。如果需要,请在查询中使用 locations_table 的 PK 和 store_name。请参阅下面的位置 id 和 store_name 的两个选项。强调两个选项之间的区别:
- 第一个选项表示每个商店位置的所有客户,每个商店位置的每个距离等级中有多少客户。
- 第二个选项表示每个商店位置的每个距离等级中有多少客户,仅针对每个客户最近的商店位置。
这是对O(n x m) 运行顺序的查询(通过customer_table 和locations_table 之间的CROSS JOIN 实现)并且随着任一表中行数的增加可能会变得相当慢。
统计所有距离等级的客户
您应该在客户与商店位置的距离之间创建一个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;
统计最近距离等级的客户
如果您只想将客户列在最近的距离类别中,那么您应该在 customer_table 和 locations_table 上设置与前一种情况相同的 CROSS JOIN,然后只需选择最低的组(即最近的商店) 在查询中使用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;