在此查询中对每个客户计数一次

Count each customer once in this query

我有两个表:一个是商店位置列表(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,因为每个客户只应计算一次。

有没有想过如何调整这个以便每个客户只计算一次?

仅对每个客户计数一次(在 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()