I would like to compute cluster of points and, for each cluster to get the sum of a specific attribute (let say, the sum of the score of each point in the cluster)
I already managed to build clusters using ST_ClusterWithin but I cannot compute the sum.
Here is what I tried :
SELECT sum(score), unnest(ST_ClusterWithin(coordinates, 0.1)) AS cluster
FROM locations
GROUP BY cluster;
But I get the following error ERROR:  aggregate functions are not allowed in GROUP BY
If I remove the GROUP BY, I get the sum of the score for all locations, which is not what I want (I want the sum for locations in the cluster)
This is a tricky one and the st_clusterwithin api doesn't seem well designed for what should be a common case.
The only solution I could find was to rejoin back on the clusters as follows:
SELECT SUM(score), cluster FROM locations, (
    SELECT unnest(ST_ClusterWithin(coordinates, 0.1)) AS cluster
    FROM locations
) as location_clustered
WHERE ST_Contains(ST_CollectionExtract(cluster, 1), coordinates)
GROUP BY cluster;
Edit: I've changed ST_CollectionHomogenize to ST_CollectionExtract(<geometrycollection>, 1) (Pick 1 for point, 2 for linestring and 3 for polygon) as suggested in this answer:
https://gis.stackexchange.com/questions/195915/
because of this bug: https://trac.osgeo.org/postgis/ticket/3569
Don't ask me why you can't do ST_Contains(<geometrycollection>, <geometry>); 
We need to convert to a multipoint which is permissable as an argument.
Meta: this question would have been a great match for https://gis.stackexchange.com/
With PostGIS 2.3, one might profit from the ST_ClusterDBSCAN function (the choice of the third parameter reduces it to hierarchical clustering) which returns directly the corresponding cluster index:
WITH stat AS (
  SELECT
    score, ST_ClusterDBSCAN(coordinates, 0.1, 1) OVER () AS cluster_id
  FROM
    tmp_locations
)
SELECT
  cluster_id, SUM(score)
FROM
  stat
GROUP BY
  cluster_id
ORDER BY
  cluster_id
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With