我有两个表:一个是商店位置列表(lat / long),另一个是客户列表(地址lat / long)。我需要的是一个查询,显示每个商店的特定范围内有多少客户。目标是让每个客户在距离商店最近的距离范围内计算一次。也就是说,每个客户只应计算一次。例如,如果他们距离一家商店2英里,距离另一家商店5英里,那么只计算它们与第一家商店相关联。
下面的查询应该完成所有这些,所以基本上我可以看到所有客户来自任何商店的最大距离。
这就是我的查询:
SELECT CASE
WHEN dist < 8046. THEN 1
WHEN dist < 16093. THEN 2
WHEN dist < 40233. THEN 3
WHEN dist < 80467. THEN 4
WHEN dist < 160934. THEN 5
END AS grp,count(*)
FROM (SELECT s.id, s.identifier, ST_Distance_Sphere(s.the_geom, c.the_geom) AS dist FROM full_data_for_testing_deid_2 c, demo_locations_table s)
AS loc_dist
GROUP BY grp
结果如下:
| Count | grp |
|---------|------|
| 2860 | 1 |
| 4858 | 2 |
| 12735 | 3 |
| 11432 | 4 |
| 23950 | 5 |
| 1002970 | null |
我的数据库中只有32048个客户,所以这不是很正常。如果是的话,我希望这些数值会线性增加,但在我的结果中,第3组第4节中的客户数量更多,但情况并非如此。此外,1-5组应该加起来为32048,因为每个客户只应计算一次。
有关如何调整此项以使每位客户只计算一次的任何想法?
答案 0 :(得分:1)
仅计算每位客户 一次 (在Postgres 9.3 +中):
SELECT CASE
WHEN s.dist < 8046.0 THEN 1
WHEN s.dist < 16093.0 THEN 2
WHEN s.dist < 40233.0 THEN 3
WHEN s.dist < 80467.0 THEN 4
WHEN s.dist < 1609340.0 THEN 5
END AS grp
, count(*)
FROM full_data_for_testing_deid_2 c
, LATERAL (
SELECT s.id, s.identifier, ST_Distance_Sphere(s.the_geom, c.the_geom) AS dist
FROM demo_locations_table s
ORDER BY dist
LIMIT 1
) s
GROUP BY 1;
这会使每个客户完全一次并在汇总之前找到最接近它的位置。
但我不认为ST_Distance_Sphere()
在the_geom
上使用GiST索引。
如果性能问题,请考虑ST_DWithin()
。